【问题标题】:Using malloc for an array of strings对字符串数组使用 malloc
【发布时间】:2020-03-15 23:12:57
【问题描述】:

我想创建一个称为参数的字符串数组,它从称为单词的字符串数组中复制条目(从单词 [1] 到结尾)。我在使用 malloc 时遇到了问题,我真的不明白我应该使用多少 malloc。 我首先将要存储的所有字符加起来。 words 中的最后一个条目始终为 NULL。

words = ["jargon","hello", "world", NULL];
int sum = 0;
for(int i = 1; words[i] != NULL; i++) {
    sum += strlen(words[i]);
}

所以我将在我的数组中包含称为参数的总和字符。所以现在我 malloc 并复制所需的条目。

char **arguments = malloc(sum * sizeof(char));
for(int i = 0; words[i] != NULL; i++) {
    strcpy(arguments[i], words[i+1]);
}

但是,我得到了内存缓冲区溢出。如果我把它改成

char **arguments = malloc(sum * sizeof(*arguments));

我克服了内存缓冲区溢出,但在下一行的 arguments[i] 中收到了一个未初始化的值。有人能解释一下发生了什么吗?

编辑:对糟糕的风格感到抱歉,并感谢您的建议。

【问题讨论】:

  • 什么是words?请提供minimal reproducible example
  • ... 很可能是malloc(sum * sizeof(char)) -> malloc(sum * sizeof(char*))
  • for(int i = 1; 0
  • @Jabberwocky:没有证据表明选择从words[1] 开始的数据是一种风格而不是功能的选择。如问题所述,这是功能要求。具体来说,它们被给了一个指针,并且所需的任务是从words[1] 开始复制。当main 的标准argv 传递给例程并且希望复制参数而不是程序名称时,就会自然而然地出现这种情况。
  • @EricPostpischil 这或多或少是发生了什么,但我找不到一种很好地表达它的方法。感谢您为我找到单词

标签: c pointers malloc c-strings


【解决方案1】:

我想创建一个称为参数的字符串数组,用于复制 来自称为单词的字符串数组中的条目

如果是这样,那么这个循环就没有意义了。

int sum = 0;
for(int i = 1; words[i] != NULL; i++) {
    sum += strlen(words[i]);
}

此外,C 中的索引从 0 开始。目前尚不清楚为什么您循环中的索引i1 开始。

您需要分配一个指针数组,然后为指针数组的元素所指向的字符串分配内存。

您需要的是以下内容

size_t n = 0;

while ( words[n] != NULL ) ++n;

char **arguments = malloc( n * sizeof( *arguments ) );

for ( size_t i = 0; i != n; i++ )
{
    size_t length = strlen( words[i] );
    arguments[i] = malloc( length + 1 );
    strcpy( arguments[i], words[i] );
}

如果你想从复制的字符串集合中排除字符串 words[0] 那么代码 sn-p 可以看起来像

size_t n = 0;

while ( words[n+1] != NULL ) ++n;

char **arguments = malloc( n * sizeof( *arguments ) );

for ( size_t i = 0; i != n; i++ )
{
    size_t length = strlen( words[i+1] );
    arguments[i] = malloc( length + 1 );
    strcpy( arguments[i], words[i+1] );
}

【讨论】:

  • 请不要只发布代码以获得答案而不解释它。说明为什么为字符总数分配空间并将其分配给指向char 的指针的指针是错误的。说明为什么必须为指针分配空间。说明为什么必须为每个字符串分配空间。说明为什么每个都必须添加一个。此外,我们不应该对忽略malloc 返回空值的可能性的代码进行建模。应尽快向学生传授良好的错误处理和稳健的编程实践。
  • @EricPostpischil 为什么不在这里开设教学班?请不要误会我的意思,我在这里提出了一个公平的观点。
  • words[1] 开头似乎是故意的,因为它在文本中明确说明并在代码中体现,包括从words[i] 复制到arguments[i-1]。后者表明 OP 知道从零开始的索引,并支持以words[1] 开头的假设是故意的。因此,暗示 OP 在这方面是错误的可能是一个错误。用它开始回答而不是从代码中的关键问题开始是一种贬义。
  • @EricPostpischil 请发布您的详尽文章,并从二进制开始。很高兴投票。
  • 尽管对索引进行了不必要的评论,但还是给出了正确的解决方案,因此被赞成。
猜你喜欢
  • 2016-01-22
  • 2011-08-21
  • 2021-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-09
  • 1970-01-01
相关资源
最近更新 更多