【问题标题】:C - Array of strings (2D array) and memory allocation gets me unwanted charactersC - 字符串数组(二维数组)和内存分配让我得到不需要的字符
【发布时间】:2013-05-31 01:19:25
【问题描述】:

我的作业有一个小问题。整个程序都是关于树数据结构的,但我对此没有任何问题。

我的问题是关于一些基本的东西:从用户输入中读取字符串,然后将它们存储在一个数组list中。

char str[1000];

fgets(str, 1000, stdin);

int x = 0;
int y = 0;
int z = 0;

char **list;
list = (char**)malloc((x+1)*sizeof(char));
list[x] = (char*)malloc((y+1)*sizeof(char));

while(str[z] != '\n')
{
    list[x][y] = str[z];
    z++;

    if(str[z] == ',')
    {

        x++;
        y = 0;

        list = (char**)realloc(list, (x+1) * sizeof(char*));
        list[x] = (char*)malloc((y + 1)*sizeof(char));

        z++;
        if(str[z] == ' ') // Skips space after the comma
        {
            z++;
        }

    }
    else if(str[z] == '\n')
    {
        break;
    }
    else
    {
        y++;
        list[x] = (char*)realloc(list[x], (y+1)*sizeof(char));

    }

}

我将此列表数组传递给另一个函数。 例如,输入可能类似于

Abcde, Fghijk, Lmnop, Qrstu

我正在尝试将这些单词中的每一个拆分为数组 list

Abcde
Fghijk
Lmnop
Qrstu

当我尝试输出字符串时,我有时会感到奇怪、过多的字符,例如倒置的问号和数字。

printf("%s ", list[some_number]);

了解我

Fghijk¿

Fghijk\200

我的所有程序都按预期工作,除了这个我无法解决的小问题。即使使用相同的确切输入,错误也可能会出现,也可能不会出现。我猜它与内存分配有关?

感谢您的帮助!

【问题讨论】:

  • 当你使用 malloc 时,不能保证你预留的内存中包含什么,你应该将它初始化为 NULL,或者至少 null 终止你的字符串。
  • 我可以看到您将内容传递给的其他函数吗?另外,这些参数是如何传递到程序中的?文件、控制台等?

标签: c arrays string memory-management multidimensional-array


【解决方案1】:

要么将你的变量初始化为空,要么像番茄所说,在新字符串的末尾放置一个空字符。

在内存管理方面,C 缺乏程序员现在认为理所当然的许多奢侈品。您使用malloc 走在正确的道路上,但该函数只分配内存......它并没有清除它。结果,您的变量将拥有正确的空间量(对于减少内存泄漏和溢出错误至关重要),但将被垃圾填充。这种垃圾可以是任何东西,在你的情况下,它是一个颠倒的问号。合适,你不觉得吗?

我可能弄错了,因为如果没有更多信息,我无法自己运行代码,但是在您的

之后
char **list;
list = (char**)malloc((x+1)*sizeof(char));
list[x] = (char*)malloc((y+1)*sizeof(char));

语句,你会想要做这样的事情:

list = NULL;

等清理垃圾。

此外,您可能需要使用strlen() 函数(包含在string.h 中)来确定您需要分配多少内存块。

清除用于变量的空格是学习 C 语言的一个好习惯。很高兴看到你也学习它。

【讨论】:

    【解决方案2】:

    查看大多数C 库函数,例如printfstrlen 进程字符串,假设\0 作为所有的结束字符。否则,他们会继续越界读取内存,要么造成内存冲突,要么获取一些值0 并停止的地方,并且内存中的所有字节都被解释为它们的extended ascii 等价物,因此你得到这样一个奇怪的行为。

    因此,为\0 字符分配一个额外的字节并将其分配给最后一个字节。

    【讨论】:

      【解决方案3】:

      您需要将 '\0' 放在新字符串的末尾。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-07
        • 1970-01-01
        • 2016-08-12
        • 2021-06-12
        • 1970-01-01
        • 1970-01-01
        • 2011-06-22
        • 1970-01-01
        相关资源
        最近更新 更多