【问题标题】:Where am I going wrong when allocating memory in this simple C program?在这个简单的 C 程序中分配内存时我哪里出错了?
【发布时间】:2018-03-10 19:27:57
【问题描述】:

程序的目标是从终端获取用户输入,然后打印出用户输入的每个单词的最后一个字符。

例如,“Hello World”应该打印出“od”。

这里是代码。当我尝试调整 char 指针的大小时,我不确定哪里出错了。代码如下。

仅当我在 gcc 的参数中使用 -fsanitize=address 时才会出现此问题

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
    char *shortened = NULL;
    int i = 1;
    while(argv[i] != NULL)
    {
        shortened = realloc(shortened, 1 * (sizeof(char)));
        int length = strlen(argv[i]);
        char* curWord = argv[i];
        shortened[i-1] = curWord[length -1];
        i++;
    }
    printf("%s\n", shortened);
    return 0;
}

【问题讨论】:

  • 它对我有用。你在看什么?你在哪个平台上工作?
  • 1 不是 i
  • @Leonard 我忘了提到它只会在我在编译程序时使用 -fsanitize=address 参数时给我一个问题。没有那个,我没有问题
  • 你为什么要分配任何内存?您的输入已经存在并且已经被标记化。您无需在堆外分配内存即可找到 argv[1] 到 argv[argc-1] 中的每个中的最后一个字符。
  • 您需要一个额外的字节空间来为您的字符串添加一个 nul 终止符,否则 printf 将导致未定义的行为。如果您没有参数,它也是未定义的行为,因为您尝试打印 NULL。

标签: c string pointers memory-management realloc


【解决方案1】:

您对 realloc 的调用总是只分配一个字符。你不想要我的角色吗? realloc(sizeof(char)*(1+i));

【讨论】:

  • sizeof (char) 定义为 1。
  • @melpomene 当然,但是 OP 使用了 sizeof(char)。有趣的是包含了 i
  • @melpomene 我知道一个 char 是一个,我只是在那里有 100% 肯定这不是导致我崩溃的问题。
【解决方案2】:

您想重新分配i 字符,加上一个作为空终止符的字符,因此更改此设置(仅分配一个字符):

shortened = realloc(shortened, 1 * (sizeof(char)));

到这里:

shortened = realloc(shortened, (i + 1) * (sizeof(char)));

【讨论】:

  • 我改变了我的代码来反映这一点,现在知道 realloc 改变了空间总量,而不是要添加多少空间。但是,当我使用 -fsanitize=address 时,我仍然遇到内存缓冲区问题。
  • @ColinNull 您是否尝试在 printf 之前附加一个空终止符?无论如何,你为什么不首先将缩短分配为 argv char 数组?
【解决方案3】:

首先,回答您的问题 - realloc 将新尺寸作为第二个参数,而不是尺寸的增加。您需要使用您拥有的单词数的计数,并相应地更改大小。

其次,argv 包含命令行参数,表示写在可执行文件名之后的标记。要从用户那里获取输入,您可能需要使用 scanf

【讨论】:

  • argv[argc] 保证为NULL
  • 哦,谢谢。我记得相反。那为什么会给出argc呢?
  • 这就是我打算从用户那里获得输入的方式。通常情况下,我会使用 scanf,但在这种情况下,我们应该通过可执行文件名称后的输入来获取。
  • @ColinNull 哦,好的。
  • @Neo 我用shortened = realloc(shortened, i+1); 替换了我之前的分配。但是,使用 -fsanitize=address 作为编译器参数,我仍然遇到内存缓冲区问题。我又误会了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-21
  • 2021-03-04
  • 2014-11-22
  • 1970-01-01
  • 2014-03-01
  • 2020-06-18
相关资源
最近更新 更多