适当的字符串内存分配

时间:2016-02-16 03:04:32

标签: c compiler-errors

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

这个在C中的目的是允许创建“地图”,我稍后将使用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
 }

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

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

2 个答案:

答案 0 :(得分:1)

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

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并分配到其中,您会得到更好的服务。有关如何执行此操作,请参阅Allocate memory 2d array in function C

答案 1 :(得分:0)

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

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

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <malloc.h>

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
}

P.S。不要心疼。无论程序员多么有经验,我们所有都会犯“愚蠢”的错误。而且,我们每隔日做。欢迎来到俱乐部!