| | |
Dynamically allocating 2d arrays
Thread Solved |
Basically I'm reading from a file and populating a dynamically allocated array with the words that are in the file. I've already read through the file to figure out what numArts is, so I know how many words there are in the array.
This works up until the:
if I remove those lines, the printf statment prints what I expect it to. I've tried doing this with pointer arithmetic as well. I just keep getting bus error over and over. From what I can tell and what I've been able to read about dynamically allocating arrays and such I'm doing this correctly. Does anyone see anything wrong with this?
This works up until the:
C Syntax (Toggle Plain Text)
arts[index] = (char*)malloc(strlen(word) * sizeof(char)); strcpy(*(arts + index), word);
if I remove those lines, the printf statment prints what I expect it to. I've tried doing this with pointer arithmetic as well. I just keep getting bus error over and over. From what I can tell and what I've been able to read about dynamically allocating arrays and such I'm doing this correctly. Does anyone see anything wrong with this?
C Syntax (Toggle Plain Text)
void populateArts(char **arts, FILE *fin, int *numArts) { int index; char* word; /* Temporary holding for each word */ arts = malloc(*numArts * sizeof(char*)); fscanf(fin, "%s", word); /* Skip over category */ /* Fill articles array */ for(index = 0; index < *numArts; index++) { fscanf(fin, "%s", word); printf("word is %s\n", word); arts[index] = (char*)malloc(strlen(word) * sizeof(char)); strcpy(*(arts + index), word); } }
>char* word; /* Temporary holding for each word */
>fscanf(fin, "%s", word);
Pointers aren't magic containers for infinite data. You need to allocate space to word before you can write to it. In this case, there's little point in using a pointer unless you want to get fancy with single character reads.
>arts[index] = (char*)malloc(strlen(word) * sizeof(char));
You cast the result of malloc in one call but not another. Consistency is more important than perfect style, but I'd still recommend removing the cast. Also, instead of
Finally, when allocating memory for a string, you need to add an extra slot for the null character. If you don't do that, you'll end up with problems later when overflowing the buffer.
Try this:
>fscanf(fin, "%s", word);
Pointers aren't magic containers for infinite data. You need to allocate space to word before you can write to it. In this case, there's little point in using a pointer unless you want to get fancy with single character reads.
>arts[index] = (char*)malloc(strlen(word) * sizeof(char));
You cast the result of malloc in one call but not another. Consistency is more important than perfect style, but I'd still recommend removing the cast. Also, instead of
sizeof(char) , you can get the same effect without specifying the type directly using sizeof *arts[index] . Also note that sizeof(char) is guaranteed to be 1.Finally, when allocating memory for a string, you need to add an extra slot for the null character. If you don't do that, you'll end up with problems later when overflowing the buffer.
Try this:
c Syntax (Toggle Plain Text)
void populateArts(char **arts, FILE *fin, int *numArts) { int index; char word[BUFSIZ]; /* Temporary holding for each word */ arts = malloc(*numArts * sizeof *arts); fscanf(fin, "%s", word); /* Skip over category */ /* Fill articles array */ for(index = 0; index < *numArts; index++) { fscanf(fin, "%s", word); printf("word is %s\n", word); arts[index] = malloc(strlen(word) + 1); strcpy(arts[index], word); } }
I'm here to prove you wrong.
Ah! I see. Fantastic. Thanks so much. I know pointers aren't "magic containers", but the only reason I was trying
is that earlier on while reading through the file I am doing this:
Which, to me, looked exactly the same as what I was doing in the other function, except for the allocating memory part, so I was getting confused as to why in countWords() I am able to read into a pointer that didn't have memory allocated to it and print out the correct results, but in populateArts() it wasn't working. Do you have some insight as to why it was working in one place, but not in another? I just would like to have the concept clarified, if you don't mind.
Thanks again!
Oh also, how do you specify what kind of syntax you are using with the CODE tags?
C Syntax (Toggle Plain Text)
char* word; fscanf(fin, "%s", word)
is that earlier on while reading through the file I am doing this:
C Syntax (Toggle Plain Text)
int countWords(FILE* fin) { int count = 0; char* temp; /* Temporary holding for each line */ fscanf(fin, "%s", temp); /* Read the category name, but don't count it */ while(*temp != '#' && !feof(fin)) { fscanf(fin, "%s", temp); printf("temp is %s\n", temp); if(*temp != '#') count++; } return count; }
Which, to me, looked exactly the same as what I was doing in the other function, except for the allocating memory part, so I was getting confused as to why in countWords() I am able to read into a pointer that didn't have memory allocated to it and print out the correct results, but in populateArts() it wasn't working. Do you have some insight as to why it was working in one place, but not in another? I just would like to have the concept clarified, if you don't mind.
Thanks again!
Oh also, how do you specify what kind of syntax you are using with the CODE tags?
•
•
•
•
Oh also, how do you specify what kind of syntax you are using with the CODE tags?
[CODE=C]
/*code goes here */
[/CODE]
also explained here
Last edited by niek_e; Nov 20th, 2008 at 11:39 am.
>Do you have some insight as to why it was working in one place, but not in another?
You got unlucky where it worked and lucky in another because bugs are more obvious when they break immediately. As for the detailed why, the random address as temp's value in countWords happened to be in your address space and writing to it happened not to cross any boundaries that would cause a segmentation fault. In populateArts, the random address wasn't nearly as benign.
>while(*temp != '#' && !feof(fin))
For future reference, feof isn't designed to be used as a loop condition like that. Because the end-of-file indicator for a stream is only set after you've tried and failed to read from the stream, loops constructed like this have an off-by-one error where the last record in the stream will be processed twice. This is easily tested and proven with a simple program:
You got unlucky where it worked and lucky in another because bugs are more obvious when they break immediately. As for the detailed why, the random address as temp's value in countWords happened to be in your address space and writing to it happened not to cross any boundaries that would cause a segmentation fault. In populateArts, the random address wasn't nearly as benign.
>while(*temp != '#' && !feof(fin))
For future reference, feof isn't designed to be used as a loop condition like that. Because the end-of-file indicator for a stream is only set after you've tried and failed to read from the stream, loops constructed like this have an off-by-one error where the last record in the stream will be processed twice. This is easily tested and proven with a simple program:
c Syntax (Toggle Plain Text)
#include <stdio.h> int main ( void ) { char buf[BUFSIZ] = "I'm a monkey! Ook ook!\n"; while ( !feof ( stdin ) ) { fgets( buf, sizeof buf, stdin ); printf ( "Processing a line: %s", buf ); } return 0; }
I'm here to prove you wrong.
![]() |
Similar Threads
- Macro for dynamically allocate multidimensional arrays (C)
- HEAP Corruption Error (C++)
- Error:Null Pointer assignment (C++)
- open a file and divide its data in arrays (C)
- help needed (C++)
- Sane way of dynamically allocating arrays beyond declaration. (C)
- C++ BASICS ==> Pointers, Call by Reference/Value, Inheritance, Functions & Arrays (C++)
- Pointers (C++)
Other Threads in the C Forum
- Previous Thread: corruption of the heap
- Next Thread: External Delaration for An Array?
| Thread Tools | Search this Thread |
* ansi api array arrays binarysearch calculate centimeter changingto char character convert copyanyfile copypdffile creafecopyofanytypeoffileinc createcopyoffile createprocess() directory dynamic execv fflush file floatingpointvalidation fork forloop frequency function getlasterror getlogicaldrivestrin givemetehcodez grade graphics gtkgcurlcompiling gtkwinlinux hardware highest histogram homework i/o inches include infiniteloop input interest intmain() iso keyboard km license linked linkedlist linux list looping loopinsideloop. lowest matrix microsoft mysql oddnumber open opendocumentformat openwebfoundation pdf pointer posix power program programming pyramidusingturboccodes radix read recursion recv recvblocked repetition reversing scanf scheduling segmentationfault send shape single socketprogramming stack standard strchr string suggestions test threads turboc unix urboc user variable whythiscodecausesegmentationfault win32api windows.h windowsapi






