簡體   English   中英

重新分配和strcpy

[英]Realloc and strcpy

我的代碼給我segfault錯誤:我不理解,調試器說錯誤來自打印storage_中的值

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]);
}

首先, 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 |
                                    +----------------------+

您似乎無法正確計算stored_的字符串長度。

您將testMessage分配給&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終止符的空間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM