2016-09-29 8 views
0
#include <stdlib.h> 
#include <stdio.h> 

char* text1 = "This is a string."; 
char* text2 = "Yet another thing."; 

void copyCodes (int* list, char* text){ 
    while(*text != 0){ 
    *list = *text; 
    list++; 
    text++; 
    } 
    *(list+sizeof(int)) = 0; 
} 

int main(void){ 
    int size = 72; //THIS IS THE ERROR 
    int* list1 = malloc(size); 
    int* list2 = malloc(size); 

    copyCodes(list1, text1); 
    copyCodes(list2, text2); 

    free(list1); 
    free(list2); 
} 

上記のコードです。
しかし、sizeを72から89の間の任意の値に変更した場合(72と89を除く)私はsysmalloc: Assertion ...というエラーが発生します。C - "sysmalloc:アサーション..."エラーいくつかのサイズの場合

なぜですか?


エラーは、私のUbuntu(16.04)マシン上で発生するが、それは私のOSX(10.11.5)マシン上で正常に動作します。

フルエラー

malloc.c:2395: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed. 
Aborted (core dumped) 

注目に値するEDIT1
MIPSアセンブリで書かれており、各配列にメモリの80のバイトを割り当てる場合、コードが動作します。 (上のCコードはアセンブリ命令の正確な翻訳です)。

+0

Iaの本*フル*コードを(私はそれがnullで終了する整数のリストが、null終端文字がすでにwhileループによってコピーされることだったと仮定し)、それを削除し、あなただけの

(strlen(text)+1)*sizeof(int) 

必要なバイトを必要とします? –

+0

@ EugeneSh.Yeah。 (私はすべてを不要にしました)。 – Olian04

+2

あなたはここにUBを持っています: '(list + sizeof(int))= 0;':オフセットは+4で、既に文字列を渡しています。実際には16を加算します。72 + 16 = 88は必要最小限です。 –

答えて

1

あなたがここに割り当てられたスペースの端部を越えて書くときに未定義の動作を呼び出すためです:

*(list+sizeof(int)) = 0; 

18文字で2番目の文字列と、listは18倍に増加し、4を想定します現在、割り当てられた72バイトの終わりを1ポイント上回っています。そして、あなたはに書き込む、上記は72 + sizeof(int) * sizeof(*list) == 72 + 16

はところで、「ファインワークス」のみ「私は起こるのを待っているものバグ穏やかに気づいていないんだ」という意味のオフセットありません。

1

問題がcopyCodes

void copyCodes (int* list, char* text){ 
    while(*text != 0){ 
    *list = *text; 
    list++; 
    text++; 
    } 
    *(list+sizeof(int)) = 0; 
} 

最初の文字列の最後の命令であることは17のサイズは、ですから、割り当てる必要がある(17 + 1)* 4 = 72バイトのすべての権利(ヌル終了がコピーされます) 、しかし最終的には、あなたは、72 + 16(なぜならポインタ演算のオフセットされたゾーンをゼロ、+ intサイズ4)である場合にはsizeof(INT)は(+4を加算する。

注2番目の文字列がそれをヌル終了文字をコピーするので、サイズは18で、72バイトでさえ十分ではありません。

それは72のために働いている理由は、安全ため運であるが、必要少なくとも72 + 16 + 4 = 92バイト安全にこの作業を行うために割り当てられた:

実際の式は次のようになります

(strlen(text)+sizeof(int)+1)*sizeof(int) 

必要なバイト数。

しかし、私はちょうど*(list+sizeof(int)) = 0;がtypo/uselessコードであると思われます。中間の領域には未定義の値があるからです。

関連する問題