【问题标题】:Realloc and strcpyrealloc 和 strcpy
【发布时间】:2012-01-25 00:04:06
【问题描述】:

我的代码给了我段错误错误:我不明白,调试器说错误来自打印存储的值_

char *stored_ = NULL;
char testMessage[15];

//strcpy(stored_, testMessage);

for (int a = 0;a < 10; a++)
{
    sprintf(testMessage,"Message::%i\n",a);
    printf("string is:%s;length is %i\n",testMessage,strlen(testMessage));

    stored_ = (char*) realloc (stored_, sizeof(char) * (strlen(testMessage) * (a+1) ));

    strcpy(&stored_[a], testMessage);
} 

for (int b = 0;b < 10; b++)
{
    printf("inside:|%s|\n",stored_[b]);
}

【问题讨论】:

  • 段错误发生在哪一行?
  • 您需要在末尾为空终止字符('\0')添加一个额外的空格。

标签: c segmentation-fault realloc


【解决方案1】:

拳头,sizeof(char)总是 1,你不需要乘以它。

其次,当你为一个字符串分配空间时,你必须使用:

malloc (strlen (string) + 1);

换句话说,你需要在结尾处为空字节留出空间。

第三,您似乎对字符指针和字符指针 指针感到困惑。 stored_ 是单个字符块,stored_[1] 仅比 stored_[0] 多一个字节,这意味着您将没有足够的空间来存储字符串。

stored_[n], n=:   0   1   2   3
                +---+---+---+---+
                |   |   |   |   |...
                +---+---+---+---+
                each of these cells is a single byte.

您要么必须自己管理单个字符块,为每个元素留出足够的空间(通过使用稀疏索引),要么拥有索引为 0、1、2 等的字符指针块,但是您'然后必须单独管理字符串分配。

下面的代码展示了如何做到这一点:

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

int main (void) {
    // An array of char pointers (C strings).

    char **stored_ = NULL;
    char testMessage[15];
    int i;

    // Populate them.

    for (i = 0; i < 10; i++) {
        sprintf (testMessage,"Message::%i",i);
        printf ("string is:%s;length is %i\n",testMessage,strlen(testMessage));

        // Reallocate array of char *, allocate room for string, then store it.

        stored_ =  realloc (stored_,sizeof (char*) * (i + 1));
        stored_[i] = malloc (strlen (testMessage) + 1);
        strcpy (stored_[i], testMessage);
    }

这就是它的核心,字符指针数组的分配与构成 C 字符串的实际字符数组分开

然后下面的代码将它们打印出来并进行清理。

    // Print them.

    for (i = 0; i < 10; i++) {
        printf("inside:|%s|\n",stored_[i]);
    }

    // Free all memory and return.

    for (i = 0; i < 10; i++) {
        free (stored_[i]);
    }
    free (stored_);

    return 0;
}

如预期的那样输出:

string is:Message::0;length is 10
string is:Message::1;length is 10
string is:Message::2;length is 10
string is:Message::3;length is 10
string is:Message::4;length is 10
string is:Message::5;length is 10
string is:Message::6;length is 10
string is:Message::7;length is 10
string is:Message::8;length is 10
string is:Message::9;length is 10
inside:|Message::0|
inside:|Message::1|
inside:|Message::2|
inside:|Message::3|
inside:|Message::4|
inside:|Message::5|
inside:|Message::6|
inside:|Message::7|
inside:|Message::8|
inside:|Message::9|

使用这种方法,每个单元格都是一个指向字符数组的指针,单独分配(保存 C 字符串):

stored_[n], n=:   0   1   2   3
                +---+---+---+---+
                |   |   |   |   |...
                +---+---+---+---+
                  |   |   |   |     +----------------------+
                  |   |   |   +---> | character array here |
                  |   |   |         +----------------------+
                  |   |   |         +----------------------+
                  |   |   +-------> | character array here |
                  |   |             +----------------------+
                  |   |             +----------------------+
                  |   +-----------> | character array here |
                  |                 +----------------------+
                  |                 +----------------------+
                  +---------------> | character array here |
                                    +----------------------+

【讨论】:

  • 第四,它是 %d,而不是 %i :)
  • 其实di至少在C99下同样有效。
【解决方案2】:

您似乎没有正确计算stored_ 的字符串长度。

您将testMessage 分配给&amp;stored_[loopindex] 的每个循环。我不确定这是否是预期的行为,但这是你正在做的,所以我希望你的第 10 次迭代给出字符串 "MMMMMMMMMessage::9\n"

反正testMessage的字符数总是一样的,所以stored_所需的存储空间可以计算为:

strlen(testMessage) // length of str to place at &stored_[a]
+ a                 // the loop index, where you're inserting testMessage
+ 1                 // important! extra char to hold the null terminator

永远不要忘记 +1,C 中的每个字符串都必须为 null terminator 留出空间。

【讨论】:

    猜你喜欢
    • 2011-07-18
    • 2014-01-31
    • 1970-01-01
    • 2016-01-21
    • 2013-04-23
    • 1970-01-01
    • 1970-01-01
    • 2018-05-26
    • 2011-12-17
    相关资源
    最近更新 更多