Вот мой код, который должен динамически выделять память для хранения строк:
#define _XOPEN_SOURCE 700
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
char **path = NULL;
path = (char **) malloc(sizeof(char *));
for (int i = 0; i < 5; i++)
{
path[i] = strdup("TEST");
path = (char **) realloc(path, sizeof(char *));
}
for (int i = 0; i < 5; i++)
{
printf("%s\n", path[i]);
}
return 0;
}
Приведенный выше код прерывается в строке, где я перераспределил память.
По моему мнению, память, выделенная для пути на первом malloc, указана ниже:
path -----> | char * | // path points to a character pointer which inturn is pointing to nothing(Dangling).
Итак, на данный момент, когда программа запускала строку:
path = (char **) malloc(sizeof(char *));
path[0] в настоящее время находится в границах, и мы можем хранить начальный адрес одной и только одной строки в path[0], а path[1] должен быть вне границ в этот момент времени.
Итак, когда мы в первый раз вошли в цикл for, в котором мы сохраняем адрес строки в path[i], мы сможем сделать это так:
path[0] = strdup("TEST"); // is in bounds.
Чтобы сохранить другую строку, нам нужно больше памяти, на которую должен указывать путь. Итак, я сделал realloc в строке чуть ниже:
path = (char **) realloc(path, (char *));
Итак, по моему мнению, путь должен выглядеть в памяти следующим образом:
path --------->|old char *|----->"TEST"
|----------->|new char *|----->(Dangling) // Pointing Nowhere.
Итак, теперь path[1] также находится в пределах границ, и мы должны иметь возможность использовать это место в памяти. Поэтому я не могу понять, почему я получаю эту ошибку сегментации, когда запускаю свой код:
*** glibc detected *** ./dynamic: realloc(): invalid next size: 0x0000000000602010 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x75018)[0x7f743153e018]
/lib64/libc.so.6(+0x7ae96)[0x7f7431543e96]
/lib64/libc.so.6(realloc+0xfa)[0x7f74315441aa]
./dynamic[0x40067f]
/lib64/libc.so.6(__libc_start_main+0xe6)[0x7f74314e7bc6]
./dynamic[0x400569]
======= Memory map: ========
00400000-00401000 r-xp 00000000 00:27 14459340 /home/xpansat/c/basic/dynamic
00600000-00601000 r--p 00000000 00:27 14459340 /home/xpansat/c/basic/dynamic
00601000-00602000 rw-p 00001000 00:27 14459340 /home/xpansat/c/basic/dynamic
00602000-00623000 rw-p 00000000 00:00 0 [heap]
7f742c000000-7f742c021000 rw-p 00000000 00:00 0
7f742c021000-7f7430000000 ---p 00000000 00:00 0
7f74312b2000-7f74312c8000 r-xp 00000000 fd:01 173 /lib64/libgcc_s.so.1
7f74312c8000-7f74314c7000 ---p 00016000 fd:01 173 /lib64/libgcc_s.so.1
7f74314c7000-7f74314c8000 r--p 00015000 fd:01 173 /lib64/libgcc_s.so.1
7f74314c8000-7f74314c9000 rw-p 00016000 fd:01 173 /lib64/libgcc_s.so.1
7f74314c9000-7f743161d000 r-xp 00000000 fd:01 27 /lib64/libc-2.11.1.so
7f743161d000-7f743181d000 ---p 00154000 fd:01 27 /lib64/libc-2.11.1.so
7f743181d000-7f7431821000 r--p 00154000 fd:01 27 /lib64/libc-2.11.1.so
7f7431821000-7f7431822000 rw-p 00158000 fd:01 27 /lib64/libc-2.11.1.so
7f7431822000-7f7431827000 rw-p 00000000 00:00 0
7f7431827000-7f7431846000 r-xp 00000000 fd:01 20 /lib64/ld-2.11.1.so
7f7431a14000-7f7431a17000 rw-p 00000000 00:00 0
7f7431a44000-7f7431a45000 rw-p 00000000 00:00 0
7f7431a45000-7f7431a46000 r--p 0001e000 fd:01 20 /lib64/ld-2.11.1.so
7f7431a46000-7f7431a47000 rw-p 0001f000 fd:01 20 /lib64/ld-2.11.1.so
7f7431a47000-7f7431a48000 rw-p 00000000 00:00 0
7fff62f8c000-7fff62fa2000 rw-p 00000000 00:00 0 [stack]
7fff62fff000-7fff63000000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Я не могу понять, что я делаю неправильно, потому что я смог запустить свой код, если изменил строку realloc, как показано ниже:
path = (char **) realloc(sizeof(char *)*8);
Если это умножение на 8, мой код запускается, но я хочу выделить именно ту память, которую хочу. Любые идеи, почему он не работает без умножения на 8.
path = (char **) malloc(sizeof(char *));
, затемpath = (char **) realloc(path, sizeof(char *));
‹- доступ кpath[1]
вfor (int i = 0; i < 5; i++)
является поведением undefined. Ты топчешь всю память, к которой не имеешь права доступа. - person Daniel Fischer   schedule 02.07.2013realloc
совершенно бессмысленно, потому что вы запрашиваете точно такой же размер, для которого изначально выделили массив. Помните, чтоsizeof(type)
— это константа времени компиляции! - person Jan Hudec   schedule 02.07.2013malloc()/calloc()/realloc()
в C не требуется, тем более не рекомендуется: stackoverflow.com/q/605845/694576 - person alk   schedule 02.07.2013