![]() |
| | #1 |
| Registered User Join Date: Feb 2009
Posts: 12
| [C] Struct allocation crash? My goal is to eventually read line by line from a file that contains combined lengths of text like those joined into the "input" variable. Currently, the code below crashes the console in windows and in linux it points to a "realloc(): invalid next size" error. I realize that most of this code is poor programming style, but I'm only looking for it to work at this point. I was wondering if there was a much more efficient way to do this code. This would probably be much easier if the number of records and the number of subnames were constant, like they are in the example "input" variable. So I guess my questions are, what is causing the code to crash and is there a more efficient way to store an unknown number of records containing an unknown number of subnames in each record? Please ask questions if I left out something important or need to clarify anything. Thanks! Code: #include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int ID;
char* name;
int subs;
char** subname;
} RECORD;
int main() {
/*Sample of what would be read from a text file*/
char input[2][80] = {"1,Entry,ProcStart,ProcLoop,ProcFunc,ProcEnd,ProcStop",
"2,Phase,ProcBegin,ProcSpin,ProcHelp,ProcEnd,ProcHalt"};
RECORD* record = (RECORD*) malloc(sizeof(RECORD));;
if(record == NULL) return -1;
int records = 0;
int loop;
for(loop=0;loop<2;loop++) {
record = (RECORD*) realloc(record, sizeof(RECORD)*(records+1));
if(record == NULL) return -1;
record[records].ID = atoi(strtok(input[loop],","));
char* temp = strtok(NULL,",");
record[records].name = (char*) malloc(sizeof(char)*(strlen(temp)+1));
if(record[records].name == NULL) return -1;
strcpy(record[records].name,temp);
record[records].subs = 0;
int i;
while((temp=strtok(NULL,","))!=NULL) {
i = record[records].subs;
record[records].subname = (char**) realloc(record[records].subname,i+1);
if(record[records].subname == NULL) return -1;
record[records].subname[i] = (char*) malloc(sizeof(char)*(strlen(temp)+1));
if(record[records].subname[i] == NULL) return -1;
strcpy(record[records].subname[i],temp);
record[records].subs++;
}
records++;
}
/*Test the resulting data to see if the variables are stored correctly*/
int x,y;
for(y=0;y<2;y++) {
printf("%d:\n",y);
for(x=0;x<record[y].subs;x++) {
printf("%s\n",record[y].subname[x]);
}
}
getchar(); /*Stops the window from closing in the Windows console*/
return 0;
}
|
| Heathtech is offline | |
| | #2 |
| Registered User Join Date: Sep 2007
Posts: 372
| Code: record[records].subname = (char**) realloc(record[records].subname,i+1); Funny enough, your multiplication by sizeof(char) in the other allocations is not necessary, since sizeof(char) is always 1. It doesn't hurt to do the multiplication, but I find it cleaner to leave it out. |
| cas is offline | |
| | #3 |
| subminimalist Join Date: Jul 2008 Location: NYC
Posts: 3,944
| Also: you should use malloc there and not realloc. Your pointer has a size of 4 -- you are not changing that. You are allocating space that the pointer points to. So you don't (and can't) change the size of the pointer, you give it somewhere to point to of whatever size. Only use realloc on a variable on which you have already used malloc.
__________________ Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS |
| MK27 is offline | |
| | #4 |
| Registered User Join Date: Dec 2006
Posts: 1,780
| Code: record[records].subname For memory-related problems, try valgrind. http://valgrind.org/ |
| cyberfish is offline | |
| | #5 |
| Registered User Join Date: Feb 2009
Posts: 12
| Thanks for your help everyone. I was not aware that I needed a sizeof(char*). I'll look that up later to learn why. I also added the malloc before the while loop to stop the "realloc()" error. I did this for both my windows version and the linux version (same code, Ubuntu is on a virtual machine). The windows one continues to crash as soon as it is run for some reason. The linux one works perfectly, though. On an unrelated note, every time I try to download Valgrind into my Ubuntu virtual machine, it makes my whole computer Blue Screen and restart. Definitely annoying on all hairs. I have another question: You may have noticed that my code does NOT include "free(...)" statements. I am relying on the OS to free that memory at the end of the application, since I will be needing to access the data throughout the life of the application. Is this acceptable, despite being against good programming? I figured it would be quite annoying to free all of the data manually, especially since I will later have many different kinds of structs each holding varying sizes of information. |
| Heathtech is offline | |
| | #6 | |
| Registered User Join Date: Dec 2006
Posts: 1,780
| Blue screen? kernel panic is black last time I checked... Oh, you mean the Windows host. Hardware problem perhaps? or maybe driver. Code: sudo apt-get install valgrind Quote:
| |
| cyberfish is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Assignment HELP!! | cprogrammer22 | C Programming | 35 | 01-24-2009 02:24 PM |
| Looking for constructive criticism | wd_kendrick | C Programming | 16 | 05-28-2008 09:42 AM |
| Concatenating in linked list | drater | C Programming | 12 | 05-02-2008 11:10 PM |
| Dynamic allocation (I thought it would crash) | Baaaah! | C Programming | 16 | 11-30-2005 05:10 PM |
| Search Engine - Binary Search Tree | Gecko2099 | C Programming | 9 | 04-17-2005 02:56 PM |