简体   繁体   English

为字符串正确分配内存

[英]proper memory allocation for strings

So I've had this problem I've been trying to solve for about 8 hours now... I've given up my search for an answer without help. 因此,我遇到了这个问题,现在已经尝试解决了大约8个小时……我放弃了在没有帮助的情况下寻找答案的机会。 I've tried using realloc() and malloc() respectively, so any input would be great! 我已经尝试过分别使用realloc()malloc() ,所以任何输入都会很棒!

The purpose of this being in C is to allow for the creation of a 'map', I will later be using ncurses to create the map. 在C语言中的目的是为了允许创建“地图”,我稍后将使用ncurses来创建地图。

the input from the file is as follows 来自文件的输入如下

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

Here is the code: 这是代码:

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
 }

I hope I'm not as stupid as I feel right now! 我希望我不会像现在这样愚蠢! Thanks :) 谢谢 :)

edit: I AM as stupid as I felt right then 编辑:我是我当时感觉愚蠢

There are quite a few things to address here. 这里有很多事情要解决。

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

This is going to overwrite the data in commands each time through the loop. 每次循环时,这将覆盖commands的数据。 When the loop exits you will have read and discarded all the data except for the last line. 当循环退出时,您将已读取并丢弃除最后一行以外的所有数据。 You'll want to either use a 2-d array, or more likely, store the data into rooms as you read it. 您可能需要使用二维数组,或者更有可能在读取数据时将其存储到rooms中。 The second way is faster and uses less memory. 第二种方法是更快的并且使用更少的内存。

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

This sort of looks like you're trying to create a 2-d array. 看起来您正在尝试创建二维数组。 Instead you'll want to do something like this: 相反,您将需要执行以下操作:

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

Note that this malloc doesn't initialize the memory. 请注意,此malloc不会初始化内存。 So your check 所以你的支票

if (rooms[i] != NULL)

Is going to give you undefined results. 将给您不确定的结果。 The contents of rooms[i] is undefined. rooms[i]内容未定义。 If you want to initialize the array to all zeros, try using memset . 如果要将数组初始化为全零,请尝试使用memset

Then: 然后:

*rooms[i] = commands[i];

Isn't going to copy over the data from commands , rather it will only copy the first character from commands . 不会复制commands的数据,只会复制commands的第一个字符。 To copy the whole string, you'll want to use strcpy or strncpy to avoid potential buffer overflow problems. 要复制整个字符串,您将需要使用strcpystrncpy来避免潜在的缓冲区溢出问题。 memcpy is also an option to copy some number of bytes instead of null-terminated C-strings. memcpy还是复制一些字节而不是以空终止的C字符串的选项。

Lastly, returning *rooms is an error waiting to happen. 最后,返回*rooms是一个等待发生的错误。 You'd be better served passing rooms in as a parameter and allocating into that. 最好将传递rooms作为参数并分配给它。 See Allocate memory 2d array in function C for how to do that. 有关如何执行此操作,请参见在函数C中分配内存2d数组

Others have pointed out some of the changes you'd need to make. 其他人指出了您需要进行的一些更改。 So, take a look at what they've said and compare your version against the one below. 因此,请看一下他们所说的话,然后将您的版本与以下版本进行比较。 This should help. 这应该有所帮助。

Here's a corrected version of your program. 这是程序的正确版本。 I had to guess at some of your intent, based upon your code and data [please pardon the gratuitous style cleanup]: 根据您的代码和数据,我不得不猜测您的一些意图[请原谅免费的样式清理]:

#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
}

PS Don't feel bad. PS不要难过。 No matter how experienced a programmer is, we all make "dumb" mistakes. 无论程序员多么有经验,我们都会犯“愚蠢”的错误。 And, we make them every day. 而且,我们每天做他们。 Welcome to the club! 欢迎来到俱乐部!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM