簡體   English   中英

C-內存分配問題-需要說明

[英]C - memory allocation issue - need explanation

最近,我遇到了C指針問題。 如您所見,我有一個循環從STDIN讀取數據。 問題是我不太了解自己所做的事情。

我為此struct_CONTAINER結構分配了內存。 我希望在其中具有BUFFER_SIZE長度的c字符串數組。 如果我理解正確,則此數組包含BUFFER_SIZE(char *)對象-這意味着此數組的權重將為8 * BUFFER_SIZE字節(每個char指針最多8個字節)。 因此,例如,如果將BUFFER_SIZE定義為值10,則該數組的長度為80個字節,整個結構的大小可能相似。

問題是我可以使用大於BUFFER_SIZE的值遍歷該指針,這對我來說很奇怪-內存不是NULL。 我知道在那個循環中我可能正在嘗試訪問其他一些已經分配的內存。 但是我不確定。 如果有人會很好並且告訴我我在做對與錯。 內存分配可能太大。 提前致謝!

char *item = NULL;

if( dup2( STDIN_FILENO, fdin ) < 0 ){
    perror( "dup2(  )" );
    exit( errno );
}

memset( reading, '\0', BUFFER_SIZE );

struct struct_CONTAINER{
    char *container[BUFFER_SIZE];
};


while( ( r_control = read( fdin, reading, BUFFER_SIZE-1 ) ) > 0 ){
    item = &shmemContainer->container[i++];
    strcpy(item, reading);
    memset( reading, '\0', BUFFER_SIZE );
}

編輯:我忘了向您展示什么是“ item”變量的類型

您的struct成員containerchar*類型,表示其字符串數組。 您正在分配給char**字符串的item地址,並嘗試調用strcpy(item, reading);

您在以下其中一項陳述中至少做錯了。

 item = &shmemContainer->container[i++];
        ^   is wrong 
 strcpy(item, reading);
         ^ or this is wrong

[答案]正如您評論的第一點是代碼中的錯誤
因為->運算符的優先級比&更高 編譯代碼時,您應該得到警告。

  • 如果第一個表達式item = &shmemContainer->container[i++]; 寫錯是這樣的:

    item = (&shmemContainer)->container[i++];

  • 並且如果是strcpy(item, reading); 錯誤是正確的,例如:

    strcpy(*item, reading);

從您的while循環中可以理解,您想將fdin字符串讀取為字符串數組,您可以執行以下操作:

while( ( r_control = read( fdin, reading, BUFFER_SIZE-1 ) ) > 0 ){
    reading[r_control] = '\0'; // null ternimate
    strcpy(shmemContainer->container[i++],reading) ;
    memset( reading, '\0', BUFFER_SIZE );
}

代碼reading[r_control] = '\\0'; 添加此內容是因為第一次缺少memset() ,請記住read()不會自行終止\\0字符串。

編輯
考慮@Digikata的注釋,因為您正在對container[]執行strcpy() ,請確保為每個字符串分配內存。

我的建議:

container[]是字符串數組,因此您可以在while循環中分配內存,例如:

i = 0;
while( ( r_control = read( fdin, reading, BUFFER_SIZE-1 ) ) > 0 ){
    reading[r_control] = '\0'; // null ternimate
    shmemContainer->container[i] = malloc(strlen(reading) + 1);
    strcpy(shmemContainer->container[i++],reading) ;
    memset( reading, '\0', BUFFER_SIZE );
}

如果丟失,則添加了內存分配。

C不會阻止您索引超出預期的存儲位置。 例如:

char astring[5] = "0123";  // there is a zero at index 4 
char* ptr = astring;       // ptr[4] == 0

printf("%c", ptr[5]);  // reads a byte beyond the end of the string array 

您的代碼需要從邏輯上防止這種情況的發生,因為那里經常有數據,但是編寫(有時甚至是讀取)數據將導致不確定的行為。 因此,在您的代碼中,容器之外的區域讀取為非NULL是正常的。

順便說一句,目前尚不清楚您是否理解指向​​c字符串的char *類型與分配的內存區域之間的區別,例如,上面代碼中的“ ptr”和“ astring”變量。 您的示例代碼不會為該字符串分配任何內存。

暫無
暫無

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

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