Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
realloc表示下一个大小无效_C_Memory_Realloc - Fatal编程技术网

realloc表示下一个大小无效

realloc表示下一个大小无效,c,memory,realloc,C,Memory,Realloc,下面是我的代码,它应该动态分配存储字符串的内存: #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++)

下面是我的代码,它应该动态分配存储字符串的内存:

#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;
}
因此,在程序运行这一行的时候:

path = (char **) malloc(sizeof(char *));
路径[0]当前在边界内,我们可以在路径[0]处存储一个且仅一个字符串的起始地址,此时路径[1]应在边界外

因此,当我们第一次进入for循环时,我们将字符串的地址存储在路径[i]中,我们将能够:

path[0] = strdup("TEST"); // is in bounds.
为了存储另一个字符串,我们需要一些路径应该指向的内存。 所以我在下面的行中做了如下操作:

path = (char **) realloc(path, (char *));
所以,根据我的说法,路径在内存中应该是这样的,如下所示:

path --------->|old char *|----->"TEST"
  |----------->|new char *|----->(Dangling) // Pointing Nowhere.
path = (char **) realloc(sizeof(char *)*8);
所以,现在路径[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 --------->|old char *|----->"TEST"
  |----------->|new char *|----->(Dangling) // Pointing Nowhere.
path = (char **) realloc(sizeof(char *)*8);

如果是8乘,我的代码运行,但我想分配我想要的确切内存,你知道为什么没有8乘,它就不能工作吗

path = (char **) realloc(path, sizeof(char *));

这将分配给下一个循环。如果您想为每个循环重新分配资源,那么更明智的做法是事先进行分配,如下所示:

换句话说,使用
path=malloc(5*sizeof(char*))
预先分配所有内存。放弃(char**)的类型转换是首选的编码实践

提前分配所有内存

path = calloc(5, sizeof(char *));
与malloc(size)相比,calloc(num,size)有两个好处。内存为零。如果num*size溢出的乘法(显然不是在本例中),则
calloc()
仍然可以正确处理它



另一种编码实践思想是:使用
ptr=malloc(sizeof(*ptr))
ptr=malloc(sizeof(char*))
有很好的优势。如果
*ptr
的类型发生更改(即使此处不太可能),则在各种
malloc()
调用中不需要更改编码。(也适用于realloc()和calloc()。

按照您的风格,更改

path = (char **) realloc(path, sizeof(char *));

这将分配给下一个循环。如果您想为每个循环重新分配资源,那么更明智的做法是事先进行分配,如下所示:

换句话说,使用
path=malloc(5*sizeof(char*))
预先分配所有内存。放弃(char**)的类型转换是首选的编码实践

提前分配所有内存

path = calloc(5, sizeof(char *));
与malloc(size)相比,calloc(num,size)有两个好处。内存为零。如果num*size溢出的乘法(显然不是在本例中),则
calloc()
仍然可以正确处理它


另一种编码实践思想是:使用
ptr=malloc(sizeof(*ptr))
ptr=malloc(sizeof(char*))
有很好的优势。如果
*ptr
的类型发生更改(即使此处不太可能),则在各种
malloc()
调用中不需要更改编码。(也适用于realloc()和calloc()。

此处

path = (char **) malloc(sizeof(char *));
您正在分配一个指向
char
的指针的指针,这是一个指向C-“字符串”的指针的空间

那么这里:

for (int i = 0; i < 5; i++)
{
   path[i] = strdup("TEST");
   path = (char **) realloc(path, sizeof(char *));
}
for(int i=0;i<5;i++)
{
路径[i]=strdup(“测试”);
path=(char**)realloc(path,sizeof(char*);
}
您不仅使用一个指向C-“string”的指针,而且对更多指针的重新分配只不过是重新分配与以前相同的大小,实际上,您的访问就像在每次迭代中为多个指针添加内存一样

这样做会覆盖未分配的内存(或已被其他程序使用)并扰乱程序内存管理

更直接的方法是:

  ...

  char ** path = NULL;

  for (size_t i = 0; i < 5; ++i)
  {
    path = realloc(path, (i+1) * sizeof(*path));
    path[i] = strdup("TEST");
  }

  ...
。。。
char**path=NULL;
对于(尺寸i=0;i<5;++i)
{
路径=realloc(路径,(i+1)*sizeof(*path));
路径[i]=strdup(“测试”);
}
...
这里

您正在分配一个指向
char
的指针的指针,这是一个指向C-“字符串”的指针的空间

那么这里:

for (int i = 0; i < 5; i++)
{
   path[i] = strdup("TEST");
   path = (char **) realloc(path, sizeof(char *));
}
for(int i=0;i<5;i++)
{
路径[i]=strdup(“测试”);
path=(char**)realloc(path,sizeof(char*);
}
您不仅使用一个指向C-“string”的指针,而且对更多指针的重新分配只不过是重新分配与以前相同的大小,实际上,您的访问就像在每次迭代中为多个指针添加内存一样

这样做会覆盖未分配的内存(或已被其他程序使用)并扰乱程序内存管理

更直接的方法是:

  ...

  char ** path = NULL;

  for (size_t i = 0; i < 5; ++i)
  {
    path = realloc(path, (i+1) * sizeof(*path));
    path[i] = strdup("TEST");
  }

  ...
。。。
char**path=NULL;
对于(尺寸i=0;i<5;++i)
{
路径=realloc(路径,(i+1)*sizeof(*path));
路径[i]=strdup(“测试”);
}
...

您的某个地方出现了缓冲区溢出。您似乎是在Linux上,所以只需在下运行它即可找到它。
path=(char**)malloc(sizeof(char*)
,然后
path=(char**)realloc(path,sizeof(char*)
注意,
realloc
完全没有意义,因为您请求的大小与最初分配给数组的大小完全相同。请记住,
sizeof(type)
是一个编译时常量!不需要在C语言中强制转换
malloc()/calloc()/realloc()
,更不建议这样做:您的某个地方存在缓冲区溢出。您似乎是在Linux上,所以只需在下运行它即可找到它。
path=(char**)malloc(sizeof(char*)
,然后
path=(char**)realloc(path,sizeof(char*)
注意,
realloc
完全没有意义,因为您请求的大小与最初分配给数组的大小完全相同。请记住,
sizeof(type)
是一个编译时常量!不需要在C中强制转换
malloc()/calloc()/realloc()
,更不建议这样做:这可能是