コードを実行しようとすると、「s1 = malloc(65536);」で 89 行目の malloc でセグメンテーション違反が発生します。calloc または realloc に変更しても持続し、82 行目または 86 行目にメモリを解放する関数がある場合は、これが書き込まれます。
*** glibc detected *** /home/purlox/whaat: free(): invalid next size (normal): 0x00000000017b32b0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x7ff4f61aeb96]
/home/purlox/whaat[0x400904]
/home/purlox/whaat[0x4024de]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7ff4f615176d]
/home/purlox/whaat[0x400699]
======= Memory map: ========
00400000-00404000 r-xp 00000000 00:15 524713 /home/purlox/whaat
00603000-00604000 r--p 00003000 00:15 524713 /home/purlox/whaat
00604000-00605000 rw-p 00004000 00:15 524713 /home/purlox/whaat
01793000-017b4000 rw-p 00000000 00:00 0 [heap]
7ff4f5f18000-7ff4f5f2d000 r-xp 00000000 08:05 4066792 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ff4f5f2d000-7ff4f612c000 ---p 00015000 08:05 4066792 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ff4f612c000-7ff4f612d000 r--p 00014000 08:05 4066792 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ff4f612d000-7ff4f612e000 rw-p 00015000 08:05 4066792 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ff4f6130000-7ff4f62e5000 r-xp 00000000 08:05 4067023 /lib/x86_64-linux-gnu/libc-2.15.so
7ff4f62e5000-7ff4f64e4000 ---p 001b5000 08:05 4067023 /lib/x86_64-linux-gnu/libc-2.15.so
7ff4f64e4000-7ff4f64e8000 r--p 001b4000 08:05 4067023 /lib/x86_64-linux-gnu/libc-2.15.so
7ff4f64e8000-7ff4f64ea000 rw-p 001b8000 08:05 4067023 /lib/x86_64-linux-gnu/libc-2.15.so
7ff4f64ea000-7ff4f64ef000 rw-p 00000000 00:00 0
7ff4f64f0000-7ff4f6512000 r-xp 00000000 08:05 4067008 /lib/x86_64-linux-gnu/ld-2.15.so
7ff4f6712000-7ff4f6713000 r--p 00022000 08:05 4067008 /lib/x86_64-linux-gnu/ld-2.15.so
7ff4f6713000-7ff4f6715000 rw-p 00023000 08:05 4067008 /lib/x86_64-linux-gnu/ld-2.15.so
7ff4f6715000-7ff4f671b000 rw-p 00000000 00:00 0
7fffa991c000-7fffa993f000 rw-p 00000000 00:00 0 [stack]
7fffa9a00000-7fffa9a01000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted (core dumped)
gdb は、「free(str->string);」それが原因でしたが、方法がわかりません。メモリの割り当てに関するエラーは特定の 1 つの場所でのみ発生し、割り当てられたメモリのサイズを現在よりも多かれ少なかれ変更しようとしました (たとえば、8 バイトだけを割り当てようとしたり、現在の 100 倍の割り当てを試みたりしました)、それでも同じセグメンテーション違反が発生しました。
whaat.c
#include "sstring.h"
#include <string.h>
#include <stdio.h>
int main(void) {
char* s1,
s2;
// 12 byte long strings
char s3[8] = "Nequeou",
s4[8] = "quisqua";
// 256 byte long strings
char s5[256] = "Pellentesque venenatis rhoncus urna id tincidunt. Quisque blandit rhoncus nisi, vel facilisis odio ornare nec. Maecenas id tellus sit amet nunc auctor commodo. Proin egestas molestie malesuada. Vestibulum in lacus quis nisl ultricies cursus non ac nullam.",
s6[256] = "Sed tristique porta lorem. Ut elementum est in magna laoreet, in lacinia ante blandit. Vestibulum condimentum sem vel ligula feugiat, vel venenatis ante placerat. Phasellus nec turpis viverra sapien vehicula sagittis vitae tincidunt lectus. Fusce posuere.";
// 65 536 byte long strings
char s7[65536],
s8[65536];
s_string ss1,
ss2,
ss3,
ss4,
ss5,
ss6,
ss7,
ss8;
FILE *LoremIpsum;
int i;
s_init(&ss3, "Nequeou ", 8);
s_init(&ss4, "quisqua ", 8);
s_init(&ss5, "Pellentesque venenatis rhoncus urna id tincidunt. Quisque blandit rhoncus nisi, vel facilisis odio ornare nec. Maecenas id tellus sit amet nunc auctor commodo. Proin egestas molestie malesuada. Vestibulum in lacus quis nisl ultricies cursus non ac nullam. ", 256);
s_init(&ss6, "Sed tristique porta lorem. Ut elementum est in magna laoreet, in lacinia ante blandit. Vestibulum condimentum sem vel ligula feugiat, vel venenatis ante placerat. Phasellus nec turpis viverra sapien vehicula sagittis vitae tincidunt lectus. Fusce posuere. ", 256);
s_init(&ss7, NULL, 65536);
s_init(&ss8, NULL, 65536);
LoremIpsum = fopen("Lorem ipsum", "r");
if(LoremIpsum == NULL) {
perror("Error opening file ");
return 1;
}
fgets(s7, 65536, LoremIpsum);
fgets(s8, 65536, LoremIpsum);
fgets(ss7.string, 65536, LoremIpsum);
ss7.string[65535] = ' ';
fgets(ss8.string, 65536, LoremIpsum);
ss8.string[65535] = ' ';
if(fclose(LoremIpsum) == EOF) {
perror("Error closing file ");
return 2;
}
s1 = malloc(8);
strcpy(s1, "");
strcat(s1, s3);
free(s1);
s_init(&ss1, NULL, 8);
s_strcat(&ss1, &ss3);
s_free(&ss1);
s_init(&ss1, NULL, 8);
s_strcat2(&ss1, &ss3);
s_free(&ss1);
s1 = malloc(256);
strcpy(s1, "");
strcat(s1, s5);
free(s1);
s_init(&ss1, NULL, 256);
s_strcat(&ss1, &ss5);
s_free(&ss1);
s_init(&ss1, NULL, 256);
s_strcat2(&ss1, &ss5);
s_free(&ss1);
s1 = malloc(65536);
strcpy(s1, "");
strcat(s1, s7);
free(s1);
s_init(&ss1, NULL, 65536);
s_strcat(&ss1, &ss7);
s_free(&ss1);
s_init(&ss1, NULL, 65536);
s_strcat2(&ss1, &ss7);
s_free(&ss1);
s_free(&ss3);
s_free(&ss4);
s_free(&ss5);
s_free(&ss6);
s_free(&ss7);
s_free(&ss8);
return 0;
}
sstring.h
#include <stdlib.h>
typedef struct {
unsigned int length;
char *string;
} s_string;
s_string *s_init(s_string *str, char *array, size_t num) {
int i;
if(str == NULL)
str = malloc(sizeof(s_string));
if(array == NULL) {
str->length = num;
if(num != 0)
str->string = malloc(num);
else
str->string = NULL;
} else {
if(num == 0) {
str->string = NULL;
for(i = 0; array[i] != '\0'; i++) {
str->string = realloc((void *)(str->string), i + 1);
str->string[i] = array[i];
}
str->length = i;
} else {
str->string = malloc(num);
str->length = num;
for(i = 0; i < num; i++)
str->string[i] = array[i];
}
}
return str;
}
void s_free(s_string* str) {
if(str != NULL && str->string != NULL) {
free(str->string);
str->length = 0;
}
}
s_string *s_strcat(s_string *destination, const s_string *source) {
int i,
j;
for(i = destination->length, j = 0; j < source->length; i++, j++)
destination->string[i] = source->string[j];
destination->length += source->length;
return destination;
}
// second version
s_string *s_strcat2(s_string *destination, const s_string *source) {
int i;
for(i = 0; i < source->length; i++)
destination->string[i + destination->length] = source->string[i];
destination->length += source->length;
return destination;
}