1

I am trying to make a function which writes strings and integers to a file. A part of my approach involves creating a 2-D dynamic array to hold a series of strings. There are no compile time errors. However, when I try to run the program (the function plus a main to test it inside) I keep getting a segmentation fault error. I have traced it so far to a particular section of code that I have highlighted below. From what I can tell, it seems that my attempts to open the array are what is causing the seg fault (I have used a debug string with a %p character in it to make sure that the array is actually in the memory). I can't for the life of me tell why though. For convenience, I've only included the code that pertains to the seg fault as well as the declarations/initializations. If you want me to provide the whole main, please let me know. To be clear, I have tried Google for a solution, but everything I've found so far either I don't understand, or doesn't pertain to my situation.

int data_cat_num=0,current_cat=0,col_index=0;
char **cat_names;

printf("How many data categories will there be?:");
scanf("%d",&data_cat_num);

cat_names=malloc(data_cat_num*50);/*Currently defaulting to 50 bytes per name*/

while(current_cat<data_cat_num){
    col_index=0;
    printf("What is the name of category %d?",current_cat+1);
    while(cat_names[current_cat][col_index]!='\n'){/*SEG FAULT TRACED TO THIS*/
    cat_names[current_cat][col_index++]=getchar();/*LOOP!!!!!*/
   }
cat_names[current_cat][col_index]='\n';
current_cat++;
}
0

3 Answers 3

3

This line:

cat_names=malloc(data_cat_num*50);

doesn't allocate 50 bytes per name; it allocates data_cat_num*50 names. You need to do this:

cat_names = malloc(data_cat_num * sizeof(char *));
int i;
for(i = 0; i < data_cat_num; i++)
    cat_names[i] = malloc(50);

The first line allocates data_cat_num names (i.e., char * variables), and later (in the for loop), 50 bytes for each name.

EDIT Also, when you free this memory, you need to do it this way:

for(i = 0; i < data_cat_num; i++)
    free(cat_names[i]);
free(cat_names);
Sign up to request clarification or add additional context in comments.

2 Comments

I feel like a complete and total idiot. Malloc was allotting space for a pointer to a pointer 50*data_cat_num bytes long. Thank you very much.
@Johnq: Happens to the best of us. Don't worry about it.
0

This line doesn't do what you think:

cat_names=malloc(data_cat_num*50);/*Currently defaulting to 50 bytes per name*/

cat_names contains pointers to the strings, not the strings themselves. So, here you're allocating enough space to store the pointers to 50 cat names, but not the names themselves.

What you'll need to do is each time you add a name, malloc that as well. So...

cat_names[current_cat] = malloc(maxNameLength*sizeof(char));

Comments

-1
char **cat_names;

This says cat_names will be a pointer to a pointer.

cat_names=malloc(data_cat_num*50);/*Currently defaulting to 50 bytes per name*/

This makes cat_names a pointer, but a pointer to garbage because the memory returned by malloc isn't initialized.

cat_names[current_cat][col_index]='\n';

Oops, you used the cat_names contents as a pointer, but it points to garbage.

2 Comments

It isn't that cat_names is not initialized. It is the OP thinks malloc is making a N*N when it is making a N structure. The failed attempt at accessing it just points back to the problem. I did not mean to mark this answer down but SO won't let me fix it either.
I didn't say cat_names isn't initialized. I said that it points to something that isn't initialized. So when he tries to use the thing it points to as a pointer, he crashes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.