这是我的代码,应该动态分配内存来存储字符串:
#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;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码在我重新分配内存的行上中断了.
根据我的说法,第一个malloc上分配给路径的内存如下所示:
path -----> | char * | // path points to a character pointer which inturn is pointing to …Run Code Online (Sandbox Code Playgroud) int *ptr;
...
realloc(ptr,++count*sizeof(int));
or
ptr=realloc(ptr,++count*sizeof(int));
Run Code Online (Sandbox Code Playgroud)
我注意到如果我多次使用第一个选项,第一个内存地址(ptr指向)的值变为未定义(尽管内存块中的所有其他值都很好,可以通过下标访问ptr).
但是,我假设所有realloc都是缩小或增加内存块的大小,并且ptr仍然指向相同的内存块,并且它的值都不会改变.因此,如果我使用第一个选项,为什么内存块中的第一个地址最终会产生意外值,因为它ptr仍然指向同一个地址?
EDIT: 我确实记得为ptr分配内存,只是没想到它的工作提到.
当你释放内存时,指向内存的指针会发生什么?他们立即变得无效吗?如果他们以后再次有效会怎么样?
当然,指针变为无效然后再次变为"有效"的通常情况是将其他对象分配到之前使用的内存,如果使用指针访问内存,那么这显然是未定义的行为.悬空指针内存覆盖了第1课,差不多.
但是如果内存再次对同一个分配有效呢?只有一种标准方式可以实现:realloc().如果你有一个指向malloc()偏移量'd存储块内某处的指针> 1,那么使用realloc()缩小块到小于你的偏移量,显然你的指针变得无效.如果你再次使用realloc()增长块至少覆盖悬空指针指向的对象类型,并且在任何情况下都没有realloc()移动内存块,悬空指针是否再次有效?
这是一个极端的案例,我真的不知道如何解释C或C++标准来解决它.以下是显示它的程序.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
static const char s_message[] = "hello there";
static const char s_kitty[] = "kitty";
char *string = malloc(sizeof(s_message));
if (!string)
{
fprintf(stderr, "malloc failed\n");
return 1;
}
memcpy(string, s_message, sizeof(s_message));
printf("%p %s\n", string, string);
char *overwrite = string + 6;
*overwrite = '\0';
printf("%p %s\n", string, string);
string[4] = '\0';
char *new_string = …Run Code Online (Sandbox Code Playgroud) 当我们尝试调整malloc使用分配的内存大小时realloc,我们通常会这样做:
char *ptr = (char *)malloc(size_1);
ptr = (char *)realloc(ptr, size_2);
Run Code Online (Sandbox Code Playgroud)
如果size_2可能大于或小于size_1.如果新大小较大,则旧数据不会丢失,新分配的字节未初始化.ptr如果旧地址处没有足够的内存来连续存储所有字节,则包含的起始地址可能会改变.realloc将旧块的内容移动到新块中,并ptr指向该新块的初始字节.
但是,如果使用分配内存calloc,我无法理解realloc函数的行为方式.有人可以给我一个关于如何realloc分配内存的工作的简要概述calloc吗?
我有一个关于realloc函数的问题.应用realloc函数后,是否会更改旧指针的内容?代码是
main () {
int *a, *b, i;
a = calloc(5, sizeof(int));
for (i = 0; i < 5; i++)
a[i] = 1;
for (i = 0; i < 5; i++)
printf("%d", a[i]);
printf("\n%p\n", a);
b = realloc(a, 200000 * sizeof(int));
if(b == NULL)
printf("error\n");
for (i = 0; i < 5; i++)
printf("%d", a[i]);
printf("\n");
for (i = 0; i < 10; i++)
printf("%d", b[i]);
printf("\n%p %p\n", a, b);
}
Run Code Online (Sandbox Code Playgroud)
输出是
11111
0x2558010
00111
1111100000
0x2558010 0x7f29627e6010
Run Code Online (Sandbox Code Playgroud)
指针仍指向同一地址,但内容已更改.
下面的代码只是我稍后使用的一个例子:
/* Extract digits from an integer and store in an array in reverse order*/
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int oct=316;
int* array=malloc(0*sizeof(int*)); //Step 1
int* temp;
size_t size=0;
while(oct/10>0 || oct%10>0){
temp=realloc(array,++size*sizeof(int)); // Step2 requires Step1
if(temp==NULL){
printf("Can't reallocate memory");
exit(-1);
}
else{
array=temp;
}
array[size-1]=oct%10;
oct/=10;
}
for(int i=0;i<size;i++)
printf("%d\n",array[i]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
realloc参考文献[1]指出:
重新分配给定的内存区域.它必须先由malloc(),calloc(),realloc()分配...
最初我编译了没有step1的代码,并且在运行它时我遇到了分段错误.然后我包括step1,现在代码编译得很好.我不想没有找到一个整数存储,所以我使用了大小分配一些空间零用malloc的.然而,malloc参考文献[2]指出:
如果size为零,则返回值取决于特定的库实现(它可能是也可能不是空指针),但返回的指针不应被解除引用.
现在,我怀疑我的实现是否可移植.我该如何解决这个问题?
我尝试过,int* array=NULL;但我遇到了分段错误.
我正在定义一种结构
typedef struct structs{
int freeSpace;
} structs;
Run Code Online (Sandbox Code Playgroud)
我正在创建一个指向结构的指针
structs* arrayOfStructs;
Run Code Online (Sandbox Code Playgroud)
我正在为该结构的5号数组分配内存
arrayOfStructs = malloc(5 * sizeof (arrayOfStructs));
arrayOfStructs[3].freeSpace = 99;
printf("\n%d", arrayOfStructs[3].freeSpace);
Run Code Online (Sandbox Code Playgroud)
在某些时候,我将该内存重新分配给大小为10的数组
arrayOfStructs = realloc(arrayOfStructs, 10 * sizeof (arrayOfStructs));
arrayOfStructs[8].freeSpace = 9;
printf("\n%d", arrayOfStructs[8].freeSpace);
Run Code Online (Sandbox Code Playgroud)
在这里,我在阵列的第13位设置了自由空间17,我希望它只有10个位置.
arrayOfStructs[13].freeSpace = 17;
printf("\n%d", arrayOfStructs[13].freeSpace);
free(arrayOfStructs);
Run Code Online (Sandbox Code Playgroud)
这为什么有效?我究竟做错了什么 ?
我目前正在C中编写一个面向数据的大量库.过去几个小时我一直在寻找一个由于内存重定位引起的悬空指针引起的段错误,并在库内部的某处重新放置.因为这个bug只是由于库中另一个部分的内存泄漏而发生,所以我想知道是否有办法让这类错误更具可重复性.
我有这个想法,也许有一种方法可以强制realloc在每次调用时重新分配已分配的内存.我希望在进行单元测试时尽早捕获这些错误.
是否有这样一个LD_PRELOAD库(或类似的)以一种方式挂钩malloc/realloc/...调用它会因为悬空指针而早期崩溃?
该库旨在跨平台,但我想内存错误是C中为数不多的便携式内容之一.
所以我遇到了一个问题,似乎realloc没有复制缓冲区中的所有数据,所以我决定运行以下代码作为测试.
#include <stdlib.h>
int main(int argc, char** argv)
{
int* tmp_array = malloc(sizeof(int) * 2);
tmp_array[0] = 1;
tmp_array[1] = 2;
tmp_array = realloc(tmp_array, 4);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我最初遇到的同样问题仍在发生,只有部分数据被复制.缓冲区中的1被复制,但2不复制.我首先为2个整数分配足够的空间,所以如果tmp_array的赋值应该是有效的.然后重新分配到4似乎有效.我甚至尝试将返回的realloc指针显式地转换为int*,但这没有帮助.
不幸的是,我无法在调试器(VS 2017)中显示我的内存窗口的屏幕截图,但它肯定会在realloc之前显示缓冲区中的1和2,并且只在realloc之后显示缓冲区中的1.
我确信我可以通过使用malloc和memcpy手动复制数据来重新实现realloc自己,但我仍然只想知道为什么这不起作用.
任何帮助是极大的赞赏!
我有以下代码:
#include <stdlib.h>
#define STRING_LENGTH 50
typedef struct entry {
char name[STRING_LENGTH];
} datum;
int main(void) {
datum *entries = NULL;
entries = (datum*) malloc(sizeof(datum)) ;
char *buffer_ = (char*) malloc(1);
free(buffer_);
void *hz = realloc(entries , 2 * sizeof(datum));
free(entries);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我编译此代码并运行二进制文件,则会出现以下错误:
*** Error in `./a.out': double free or corruption (fasttop): 0x00005572b0381010 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x70bfb)[0x7ff4b3842bfb]
/lib/x86_64-linux-gnu/libc.so.6(+0x76fc6)[0x7ff4b3848fc6]
/lib/x86_64-linux-gnu/libc.so.6(+0x7780e)[0x7ff4b384980e]
./a.out(+0x799)[0x5572af4ca799]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf1)[0x7ff4b37f22e1]
./a.out(+0x63a)[0x5572af4ca63a]
======= Memory map: ========
5572af4ca000-5572af4cb000 r-xp 00000000 00:29 13267238517 a.out
5572af6ca000-5572af6cb000 r--p 00000000 00:29 13267238517 …Run Code Online (Sandbox Code Playgroud)