适当的字符串内存分配

所以我遇到了这个问题,我现在已经试着解决了大约8个小时……我已经放弃了寻求答案而没有帮助。 我已经尝试分别使用realloc()malloc() ,所以任何输入都会很棒!

这个在C中的目的是允许创建一个’map’,我稍后将使用ncurses来创建地图。

文件的输入如下

 10X16 de4 dw9 ds8 g8,7 m3,4 h6,5 p2,2 6X20 dn5 ds4 W4,3 e2,12 M1,1 10X13 ds3 dw9 10X12 5X4 6x12 

这是代码:

 char *importLevel() { FILE *fPointer; fPointer = fopen("Level", "r"); //Opens text file to read char* rooms[150];// set up for memory allocation char commands[150];// set up for pulling data from read file while (!feof(fPointer)) { fgets(commands,150, fPointer); // this takes each line from the file } *rooms = (char *) malloc(150 * sizeof(char)); // memory allocation for (int i = 0; i < 150; i++) { if (rooms[i] != NULL) { *rooms[i] = commands[i]; // supposed to give rooms the string } } fclose(fPointer);// close file return *rooms; // return pointer } 

我希望我不像现在这样愚蠢! 谢谢 :)

编辑:我觉得我觉得自己很愚蠢

其他人指出了你需要做出的一些改变。 所以,看看他们说了什么,并将你的版本与下面的版本进行比较。 这应该有所帮助。

这是您的程序的更正版本。 根据你的代码和数据,我不得不猜测你的一些意图[请原谅无偿的风格清理]:

 #include  #include  #include  #include  #include  char ** importLevel() { FILE *fPointer; char commands[150]; // file line buffer int roomcnt = 0; char *cp; char *bp; char **rooms = NULL; // set up for memory allocation fPointer = fopen("Level", "r"); // Opens text file to read if (fPointer == NULL) { printf("importLevel: unable to open file -- %s\n",strerror(errno)); exit(1); } while (1) { // this takes each line from the file cp = fgets(commands, sizeof(commands), fPointer); if (cp == NULL) break; // setup buffer for strtok bp = commands; // parse all words on line while (1) { // NOTE: the first assumes you want "g8,7" within a room // the second assumes you want "g8,7" as two separate rooms #if 1 cp = strtok(bp," \n"); #else cp = strtok(bp," ,\n"); #endif // strtok wants this on 2nd and subsequent loops for this line bp = NULL; // bug out if no more words on this line if (cp == NULL) break; // increase room list size (allow space for terminator) // NOTE: rooms will be preserved when we return from this function rooms = realloc(rooms,sizeof(char *) * (roomcnt + 2)); // NOTE: cp is pointing to something in our stack frame that // will go away when we return or when we read the next line // so we must preserve it in the heap now cp = strdup(cp); // add the contents of the room rooms[roomcnt] = cp; // advance count of number of rooms ++roomcnt; } } // add terminator to list if (rooms != NULL) rooms[roomcnt] = NULL; fclose(fPointer); // close file return rooms; // return pointer } 

PS不要心疼。 无论程序员多么有经验,我们都会犯“愚蠢”的错误。 而且,我们每天都在制作它们。 欢迎来到俱乐部!

这里有很多事情需要解决。

 while (!feof(fPointer)) { fgets(commands,150, fPointer); // this takes each line from the file } 

这将在每次循环时覆盖commands的数据。 当循环退出时,您将读取并丢弃除最后一行之外的所有数据。 您需要使用二维数组,或者更有可能在阅读时将数据存储到rooms中。 第二种方式更快,使用更少的内存。

 *rooms = (char *) malloc(150 * sizeof(char)); 

这种看起来像是在尝试创建一个二维数组。 相反,你会想做这样的事情:

 for (int ii = 0; ii < 150; ++ii) rooms[ii] = malloc(150 * sizeof(char)); 

请注意,此malloc不会初始化内存。 所以你的支票

 if (rooms[i] != NULL) 

会给你不明确的结果。 rooms[i]内容未定义。 如果要将数组初始化为全零,请尝试使用memset

然后:

 *rooms[i] = commands[i]; 

不会复制commands的数据,而只会复制commands的第一个字符。 要复制整个字符串,您需要使用strcpystrncpy来避免潜在的缓冲区溢出问题。 memcpy也是复制一些字节而不是以空字符结尾的C字符串的选项。

最后,返回*rooms是一个等待发生的错误。 作为参数传递rooms并分配到那里你会更好。 请参阅functionC中的分配内存2darrays以了解如何执行此操作。