我将解释我所做的简短编码步骤以及我面临问题的区域
int main()
{
int cnt_map,i=1,value;
/* My question is about this char pointer "key" */
char *key =(char*)malloc(sizeof(char) * 25);
if(key!=NULL)
{
printf("Key value is not NULL,its value is:%x\n",key) ;
cout<< "Enter the number of elements required in container map"<<endl;
cin >> cnt_map;
for (i=1;i<=cnt_map;i++)
{
cout << "Enter the key : ";
cin >>key;
cout << "Enter the key value:" ;
cin >>value;
printf("value pointed by ptr key: %s, value in ptr: %x\n", key,key);
c -> add_map1(key,value); //Function inserts value to map container
key+=sizeof(key);
}
c -> size_map1(); //Function displays size of map container
c -> display_map1(); //Function displays contents of map container
if(key)
{
printf("FINALLY:value pointed by ptr key: %s, value in ptr: %x,size:%d\n",key, key, sizeof(key));
free(key);
}
}
return 0;
}
在尝试编译并运行上面的代码时,我能够成功编译代码,但在尝试运行应用程序时“检测到glibc:双重释放或损坏”。
现在我的问题是我创建了一个字符指针(char *key =(char*)malloc(sizeof(char) * 25);
)
并使用malloc为其成功分配了内存。完成我的过程后,当我尝试释放该指针时,我得到双重免费或损坏错误。我了解到,应该最终释放任何带有malloc / calloc的变量分配内存。请告诉我为什么这会出现错误,为什么我不应该这样做?请告诉我char* key
内存操作是如何进行的(如果可能,请以图片形式展示)。
注意:上面提到的代码不是完整的代码,我刚刚解释了我遇到问题的地方, 如果我没有释放指针变量,我的应用程序运行成功。
非常感谢任何帮助。非常感谢提前。
答案 0 :(得分:7)
通过这样做:
key+=sizeof(key);
您的key
变量不再指向您分配的内存的开头。您必须将原始指针传递给free()
。您需要将原始指针存储在另一个变量中,以便最后能够正确free()
。
(你可以简单地删除那一行 - 我不知道它在做什么,因为sizeof(key)
是4或8.我怀疑它是多余的。)
答案 1 :(得分:5)
这是因为这一行:key+=sizeof(key);
。 key
不包含与malloc
返回的地址相同的地址。
例如:
char *key =(char*)malloc(sizeof(char) * 25);
假设malloc返回地址20000
(完全是愚蠢的地址,仅用于示例)。
现在你正在做key+=sizeof(key);
,所以key = 20000 + 4 = 20004.问题是你正在尝试释放key
,它指向地址20004而不是20000。
为了解决这个问题,请尝试以下方法:
int main()
{
int cnt_map,i=1,value;
char *key_save;
/* My question is about this char pointer "key" */
char *key =(char*)malloc(sizeof(char) * 25);
key_save = key;
if(key!=NULL)
{
printf("Key value is not NULL,its value is:%x\n",key) ;
cout<< "Enter the number of elements required in container map"<<endl;
cin >> cnt_map;
for (i=1;i<=cnt_map;i++)
{
cout << "Enter the key : ";
cin >>key;
cout << "Enter the key value:" ;
cin >>value;
printf("value pointed by ptr key: %s, value in ptr: %x\n", key,key);
c -> add_map1(key,value); //Function inserts value to map container
key+=sizeof(key);
}
c -> size_map1(); //Function displays size of map container
c -> display_map1(); //Function displays contents of map container
if(key)
{
printf("FINALLY:value pointed by ptr key: %s, value in ptr: %x,size:%d\n",key, key, sizeof(key));
free(key_save);
}
}
return 0;
}
答案 2 :(得分:1)
只需删除该行:
key+=sizeof(key);
key
不是指向字符串数组的指针,它是指向单个字符串的指针。每次递增时,都会减少字符串中的可用空间。第一次读取密钥时,有25个字节可用。下一次,您将key
增加了4或8个字节,但分配的空间的末尾没有改变,所以现在只有21或17个字节可用。第三次它只有17或9个字节,依此类推。经过几次迭代后,您将增加key
超过您分配的内存块的末尾,它将开始写入未分配的内存(或分配给其他数据结构的内存)。这是未定义的行为,很可能会导致程序出现不可预测的故障。
由于您使用的是C ++,因此您应该使用std::string
代替char[]
代替字符串,而std::vector
代替普通数组。这些数据结构会根据需要自动扩展,因此可以避免像这样的缓冲区溢出。
答案 3 :(得分:0)
这不考虑您的代码,但我在Reader writer问题(操作系统)http://en.wikipedia.org/wiki/Readers%E2%80%93writers_problem中遇到了同样的问题。
这是由于文件指针是全局的,所以每当任何读者试图读取时,在黑白中另一个读取读取和关闭文件指针,这样当另一个未完成读取的读取器尝试在读取后关闭文件指针。所以发生的事情是文件指针已经关闭它没有指向任何文件。 解决方案我用过。 它不是声明文件指针全局,而是将它声明为读取器函数的本地,或者你可以检查文件指针是否为NULL,如果为NULL则不要关闭文件指针。
#include<stdio.h>
#include<semaphore.h>
#include<pthread.h>
#include<string.h>
#include<stdlib.h>
sem_t x,wsem;
int rc=0;
char ch;
char str[20];
void *reader(void *);
void *writer(void *);
int main()
{
int nw,nr,i=0,j=0;
pthread_t w[10],r[10];
sem_init(&x,0,1);
sem_init(&wsem,0,1);
rc=0;
printf("Enter the no of readers:");
scanf("%d",&nr);
printf("Enter the no of writers");
scanf("%d",&nw);
while(i<nw || j<nr)
{
if(i<nw)
{
pthread_create(&w[i],NULL,writer,(void *)i);
i++;
}
if(j<nr)
{
pthread_create(&r[j],NULL,reader,(void *)j);
j++;
}
}
for(i=0;i<nw;i++)
{
pthread_join(w[i],NULL);
}
for(j=0;j<nr;j++)
{
pthread_join(r[j],NULL);
}
return 0;
}
void *reader(void *arg)
{
FILE *fptr;
sem_wait(&x);
rc++;
if(rc==1)
sem_wait(&wsem);
sem_post(&x);
printf("\nreader %d:",arg);
fptr=fopen("temp.txt","r+");
while(fgets(str,10,fptr)!=NULL)
{
printf("%s",str);
}
printf("\n");
fclose(fptr);
sem_wait(&x);
rc--;
if(rc==0)
sem_post(&wsem);
sem_post(&x);
}
void *writer(void *arg)
{
FILE *fptr1;
sem_wait(&wsem);
printf("\nwriter-%d:\n",arg);
fptr1=fopen("temp.txt","a+");
printf("enter the string:");
scanf("%s",str);
fputs(str,fptr1);
fclose(fptr1);
sem_post(&wsem);
}