Problem with using uninitialized variables [closed] - c

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I have two code snippets. Both give me a warning about using uninitialized variables, however, the former throws a segmentation fault while the latter DOESN'T. Please point out what has caused the difference here.
EDIT: They said it is undefined behaviour. So to be clear, i make a char **eligible_file which is undefined, then how can i get around with this without setting a fixed size for the variable?
the first:
glob_t glob1;
glob("*.log", GLOB_ERR, NULL, &glob1);
char** file_name = glob1.gl_pathv;
int file_num = glob1.gl_pathc;
char** eligible_file;
int j = 0;
if (compare_string(argv[1], "-o")) {
for (int i = 0; i < file_num; i++) {
int rc = file_or(file_name[i], argv, 2, argc);
if (rc == 0) {
eligible_file[j] = file_name[i]; // the fault occurs here
j += 1;
}
}
} else {
for (int i = 0; i < file_num; i++) {
int rc = in_file(file_name[i], argv, 1, argc);
if (rc == 0) {
eligible_file[j] = "xasdax"; // the fault occurs here
j += 1;
}
}
}
the latter:
char** fake;
char* me[] = {"qwedsa", "wqdxs", "qwdsx"};
if (1) {
for (int i = 0; i < 3; i++) {
fake[i] = me[i];
}
} else {
for (int i = 0; i < 3; i++) {
fake[i] = "wqxsaa";
}
}

In both code snippets you write to a pointer without allocating memory for it.
1st snippet:
char** eligible_file;
...
eligible_file[j] = file_name[i]; // the fault occurs here
j += 1;
and
char** eligible_file;
...
eligible_file[j] = "xasdax"; // the fault occurs here
j += 1;
2nd snippet:
char** fake;
fake[i] = me[i];
...
fake[i] = "wqxsaa";
I am almost sure that in all cases, the error appears when the array index becomes greater than 0 - that is when writing in un-allocated memory occurs.
You should allocate memory in either of two ways:
Use proper arrays instead of pointers;
use malloc() or other similar function to allocate (enough) memory.
"undefined behavior" = whatever happens, good or bad, do not ask "why?"

Related

Segmentation fault (core dump) with multiplication of dynamic matrices [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I'm writing this code but it's continue on giving me a core dump error but i cannot understand why...This code takes 4 int inputs and two double matrices and gives me two outputs (result and the product matrix). I think the problem is in the allocation but I'm not sure... Thanks in advance for your help!
double **calculate product (double** matrix1,
double** matrix2,
int *result,
int dim_rows1,
int dim_rows2,
int dim_col1,
int dim_col2)
{
int i, j, k;
double** prod_matrix = NULL;
if(matrix1 == NULL || matrix2 == NULL)
*result = 0;
else
{
*result = 1;
if(dim_col1 == dim_rows2)
{
prod_matrix = (double **)malloc((dim_rows1)*sizeof(int *));
for(i = 0; i < dim_rows1; i++)
{
prod_matrix[i] = (double *)malloc((dim_col2)*sizeof(int));
}
for(i = 0; i < dim_rows1; i++)
{
for(j = 0; j < dim_col2; j++)
{
prod_matrix[i][j] = 0;
for(k = 0; k < dim_rows2; k++)
{
prod_matrix[i][j] += matrix1[i][k]*matrix2[k][j]
}
}
}
}
else
*result = 0;
return(prod_matrix);
}
An example of main is:
int main (void){
int result,
dim_col1,
dim_col2,
dim_rows1,
dim_rows2,
selected;
double **matrix1 = NULL,
**matrix2 = NULL,
**sum_matrix = NULL,
**prod_matrix = NULL;
selected = text(); /* client chose a number beetween 1 and 6*/
switch(selected)
{
case 1: /* case 1 and case 2 take the dimension of the matrix */
.
.
.
case 5: /* makes sum beetween matrix */
.
.
case 6: prod_matrix = prod_matrix (matrix1, matrix2, &result, dim_rows1 . . . dim col2)
if(result == 1)
//do things
else
//do things
}
return(0);
}
I forgot to say, usally it works but when i try with the first one matrix (4,2) and the second one (3,4) it goes always in segmentation fault.
Eljay has it.
prod_matrix[i] = (double *)malloc((dim_col2)*sizeof(int));
should be
prod_matrix[i] = (double *)malloc((dim_col2)*sizeof(double));

Storing first characters of elements in a string [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 4 years ago.
Improve this question
How can I store the first character of an element in a string? E.g. if I run
for (j=0; j < 5; j++) {
printf("%s\n, string[j]);
}
I get
hello
how
are
you
Thanks to the answer provided by #Holy semicolon, I know that I can run printf("%c\n, string[j][0]); to print the first letters:
h
h
a
y
However, how can I store the first letters in a new array?
So far, I have:
char secondStr[10];
for (j=0; j<5; j++) {
secondStr[j] = string[j][0];
}
This results in an error assignment makes pointer from integer without a cast
I know this question is slightly different to the one I asked before (regarding printing the first elements) - I was unsure whether or not to ask an entirely new question on SO. I apologise in advance if I was supposed to ask a new question.
when you have an array of pointers to char *string1[] = {"hello", "how", "are", "you"}; and you want to print the first string of it hello so you must use %s for string like this printf("%s",string1[0]) but if you want to print the first char of the first string you need to use %c like this printf("%c",string1[0][0]).
#include <stdio.h>
int main()
{
char *string1[] = {"hello", "how", "are", "you"};
printf("%s",string1[0][0]); // I think you did this fault It'll give you Segmentation fault
return 0;
}
so as you see in the code above you need to replce %s with %c.
Edit
What if I wanted to store the first letters in a new list?
you will need then to allocate memory to the new string.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *string1[] = {"hello", "how", "are", "you"};
char **keep = calloc(sizeof(char*),5); //memory allocating
for (int index = 0; index <= 3; index++)
{
keep[index] = calloc(sizeof(char),2); //memory allocating
keep[index][0] = string1[index][0];
keep[index][1] = '\0';
}
//for test
for (int i = 0; i <= 3; i++)
printf("%c\n",keep[i][0]);
return 0;
}
If string is std::string, then:
string s[6] = { "hello","how", "are", "you", "?" };
for (int j = 0; j < 5; j++)
{
if(s[j].size())
printf("%c\n", s[j].c_str()[0]);
}
Should word.
Many options are there. I will just mention some.
Use begin()
for( int i = 0 ; i < num ; i++ )
{
string:: iterator it = String[i].begin();
cout << *it;
}
Use front()
for( int i = 0 ; i < num ; i++ )
{
cout << String[i].front();
}
Use at()
for( int i = 0 ; i < num ; i++ )
{
cout << String[i].at();
}
You can just go through the member functions of string and use it to your purpose

Segmentation Fault:11 in C [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am writing a program in C that replaces a number in a char* called "template" with a string, but I continually get a Segmentation Fault: 11 error.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
char *rep_str(const char *s, const char *old, const char *new1){
char *ret;
int i, count = 0;
int newlen = strlen(new1);
int oldlen = strlen(old);
for (i = 0; s[i] != '\0'; i++){
if (strstr(&s[i], old) == &s[i]){
count++;
i += oldlen - 1;
}
}
ret = (char*)malloc(i + count * (newlen - oldlen));
if (ret == NULL)
exit(EXIT_FAILURE);
i = 0;
while (*s){
if (strstr(s, old) == s){ //compare the substring with the newstring
strcpy(&ret[i], new1);
i += newlen; //adding newlength to the new string
s += oldlen;//adding the same old length the old string
} else {
ret[i++] = *s++;
}
}
ret[i] = '\0';
return ret;
}
char* madlib_by_numbers(char* temp, int word_count, char* words[]){
char* numbers[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
int tempSize = strlen(temp);
for (int i = 0; i < tempSize; i++){
if (isdigit(temp[i])){
for (int j = 0; j < (sizeof(numbers) / sizeof(char*)); j++){
temp = rep_str(temp, numbers[j], words[j]); //it makes it to this line, but never gets to assert()
}
}
}
return temp;
}
int main() {
char* temp1 = "The 1 0 likes to 2 in the moonlight.";
char* words[] = {"git", "brilliant", "swim"};
char* result = "The brilliant git likes to swim in the moonlight.";
int stringLength = strlen(result);
char* test = madlib_by_numbers(temp1, 3, words);
assert(strncmp(test, result, stringLength) == 0);
free(test);
return 0;
}
and when I run the debugger, it simply says: Segmentation Fault: 11
What i just want to understand is where the segmentation fault error is coming from, I have the suspicion one of my loops is running too many times.
There are a few issue with your code. However, the direct answer to your question is in this loop:
for (int j = 0; j < (sizeof(numbers) / sizeof(char*)); j++){
temp = rep_str(temp, numbers[j], words[j]);
}
You are calling rep_str for every digit while you mean call rep_str only if the digit in temp matches the corresponding digit in numbers. So add this conditional if(strcmp(temp,numbers[j]) == 0) right before the line temp=.... Then it'll solve your current problem.
The segfault is caused because there are only three elements in the words array. Your old loop indexes from 0 to 9 and fails when j=3, out of bound.
Also, delete the free() at the end of your program. test was never allocated and will cause a core dump.
ret = (char*)malloc(i + count * (newlen - oldlen));
There are a few problems with this line of code.
For a start, don't cast malloc (or any void * that you're assigning to a variable of different pointer type, or vice versa).
If you intended to allocate space to store a string, where's the string-terminating '\0' going to go? You need to realise that for an empty old string, this will be malloc(0) and zero bytes is not enough to store an empty string.
There's also a problem if you expect that old may be a substring of new (for example, you're replacing "0" with "hell0"). You'll need to tweak your algorithm to handle this problem. I'll leave that as a challenge for you to attempt :)
for (int i = 0; i < tempSize; i++){
if (isdigit(temp[i])){
for (int j = 0; j < (sizeof(numbers) / sizeof(char*)); j++){
temp = rep_str(temp, numbers[j], words[j]); //it makes it to this line, but never gets to assert()
}
}
}
users previous answer highlighted this code correctly, but not for the right reason... and so the solution he/she presented is wrong.
isdigit(temp[i]) may also cause segfaults for some inputs. I recommend using isdigit((unsigned char) temp[i]) instead, in this case.
It's not valid to access words[j] where word_count is 3 and j is greater or equal to 3; you're accessing that array out of bounds.
You also need to be careful to free any memory you *alloc (while simultaneously not freeing memory that you don't *alloc). Forgetting to do the former won't cause crashes, but your program won't run happily; it'll use heaps of memory.
Consider something like this, instead:
temp = strdup(temp);
if (temp == NULL) {
exit(EXIT_FAILURE);
}
for (int i = 0; i < tempSize; i++){
if (isdigit((unsigned char) temp[i])){
for (int i = min(word_count, sizeof(numbers) / sizeof(char*)), j = 0; j < i; j++){
char *new = rep_str(temp, numbers[j], words[j]);
free(temp);
temp = new;
}
}
}

strlen and free memory [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I allocated memory to a pointer to the maximum size of characters it could have.
Then I had to write code that will change its values depending on the value that was read from the file and I needed to know what is the length of the value in the pointer, so I used strlen() function.
I got what I needed.
The problem occured when I tried to free the memory of that pointer. The program crashed, I'm assuming im doing something "ilegal" and would like to know why and how to fix it.
here is part of the code:
char *StudID = (char*)malloc(sizeof(char)*15);
char *StudIDcpy = (char*)malloc(sizeof(char) * 15);
fread(stud[i].ID, sizeof(char), 4, in);
stud[i].ID[4] = '\0';
IDtemp = atoi(stud[i].ID);//convert ID string to integer and store value in IDtemp
StudIDcpy = itoba(IDtemp);//convert integer to binary number as a string
strcpy(StudID, StudIDcpy);
IDtemp = strlen(StudIDcpy);
free(StudIDcpy); // <---- I BELIEVE THIS IS WHERE IT CRASHES
Here is my itoba() function:
char *itoba(int a){
int i = 0, j;
char temp[15];
while(a){
if (a % 2)temp[i] = '1';
else temp[i] = '0';
i++;
a = a / 2;
}
temp[i] = '\0';
for (j = 0; j < i / 2; j++)swapc(&temp[j], &temp[i - j-1]);
return temp;
}
By the way I know I don't have to write sizeof(char) because it is equal to 1, but I write it anyways so I remember what value should be put there.
In your itoba() function, temp, a local array, which decays to a pointer to local variables, is returned.
After a function returns, its local variables are "free"ed immediately, allowing these memory space to be reused by someone else. Consequently, values held by them will soon be overridden by other values on the stack.
You can rewrite itoba() like this:
char *itoba(int a)
{
int i = 0, j;
char *temp = malloc(15); // <--- This line is different
while(a){
if (a % 2)
temp[i] = '1';
else
temp[i] = '0';
i++;
a = a / 2;
}
temp[i] = '\0';
for (j = 0; j < i / 2; j++)
swapc(&temp[j], &temp[i - j -1]);
return temp;
}
BTW: You should remove char *StudIDcpy = (char*)malloc(sizeof(char) * 15);, because the pointer value returned by malloc() is later discarded by itoba(IDtemp);. As a result, the memory allocated to StudIDcpy by this malloc() will never be freed, causing memory leak.

free(ptr) crashes sometimes, pointer is always valid [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am trying to create some streams of bytes, dynamically allocated, and perform a copy of them in some other place. My code is this (earlier i didn`t type from a pc :) ):
void construct_cypherstreams(uint8_t * stream, int key_length, int stream_length, uint8_t ** encr_streams, int * bytes_in_stream) {
// chyperstream = the stream formed of every ith byte
uint8_t * cypherstream;
int length;
length = stream_length / key_length + 1;
// each byte of the key can have values
// between 0 and 256
int i = 0;
int num_added = 0;
for (int k = 0; k < key_length; k++) {
printf("\n%s %d\n", "iteration", k);
i = k; num_added = 0;
cypherstream = (uint8_t *)malloc(length * sizeof (char));
if (cypherstream == NULL) {
printf("%s\n", "could not allocate");
exit(1);
}
else {
printf("%s\n", "succesfully allocated");
}
while (i < stream_length) {
// construct cypherstream
cypherstream[num_added] = stream[i];
num_added++;
i += key_length;
}
printf("\n%s\n", "created cypherstream:");
for (int m = 0; m < num_added; m++) {
printf("%X", cypherstream[m]);
}
printf("\n");
printf("%s\n", "making deep copy...");
encr_streams[k] = (uint8_t *)malloc(num_added * sizeof(char));
// perform deep copy of characters
for (int n = 0; n < num_added; n++) {
encr_streams[k][n] = cypherstream[n];
}
printf("%s\n", "done making deep copy");
free(cypherstream);
printf("%s\n", "succesfully freed");
printf("%s %d\n", "position:", k);
printf("%s %d\n", "num_added:", num_added);
bytes_in_stream[k] = num_added;
printf("%s\n", "iteration ended");
}
}
And I call it like this:
uint8_t ** encr_streams;
int * bytes_in_stream;
encr_streams = (uint8_t **)malloc(key_length * sizeof **encr_streams);
bytes_in_stream = (int *)malloc(key_length * sizeof *bytes_in_stream);
construct_cypherstreams(stream, key_length, stream_length, encr_streams, bytes_in_stream);
Now my program sometimes runs, sometimes crashes.
I am stuck here for the moment and I could really use some help.
Compiler: msvc
Thanks
encr_streams = (uint8_t **)malloc(key_length * sizeof **encr_streams);
just looks wrong. I think it should be
encr_streams = malloc(key_length * sizeof *encr_streams);
because you seem to intend to allocate an array of pointers to uint8_t. Then you probably also have to initialize the elements of that array by something.
This is a case of heap corruption as you are trying to overwrite some dynamically allocated memory.
If you program on Linux, run your code under the valgrind memory debugger:
http://valgrind.org/docs/manual/quick-start.html
For Windows... you may want to try MS AppVerifier though I haven't used it for years and forgot almost everything about it :-(
How to use Microsoft Application Verifier

Resources