C 尝试释放内存时出现分段错误
我有下面的代码,当我得到分段错误时和没有分段错误时,我都在其中进行了注释 起初,我遇到了分段错误,然后我发现可能无法初始化字符指针位置,如C 尝试释放内存时出现分段错误,c,segmentation-fault,C,Segmentation Fault,我有下面的代码,当我得到分段错误时和没有分段错误时,我都在其中进行了注释 起初,我遇到了分段错误,然后我发现可能无法初始化字符指针位置,如“abcd”。但我无法理解——为什么 我想,testString=“abcd”将把a放在第一个内存地址,把b放在第二个内存地址,依此类推 根据我初始化内存位置的方式,尝试释放内存时会出现分段错误 #include <stdio.h> #include <stdlib.h> int main(void) { char* test
“abcd”
。但我无法理解——为什么
我想,testString=“abcd”
将把a
放在第一个内存地址,把b
放在第二个内存地址,依此类推
根据我初始化内存位置的方式,尝试释放内存时会出现分段错误
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char* testString = malloc(sizeof(char) * 5);
printf("Size of char is: %d\n", sizeof(char));
printf("Size of int is: %d\n", sizeof(int));
for(int i = 0; i < 5; i++)
{
printf("Pointer addresses are: %p\n", testString + i);
}
char* tempPtr = testString + 2;
printf("My temp pointer address = %p\n", tempPtr);
// This gives me segmentation fault ....
testString = "abcd";
// This will not give me segmentation fault ....
//int count = 65;
//for(int i = 0; i < 5; i++)
//{
// testString[i] = count + i;
//}
printf("Printing character...\n");
for(int i = 0; i < 5; i++)
{
printf("Characters are: %c\n", testString[i]);
}
printf("Freeing memory...\n");
free(testString);
//printf("Access after freeing >>%c<<\n", tempPtr[0]);
//free(testString);
}
#包括
#包括
内部主(空)
{
char*testString=malloc(sizeof(char)*5);
printf(“字符大小为:%d\n”,大小为(字符));
printf(“int的大小为:%d\n”,sizeof(int));
对于(int i=0;i<5;i++)
{
printf(“指针地址为:%p\n”,testString+i);
}
char*temptr=testString+2;
printf(“我的临时指针地址=%p\n”,temptr);
//这给了我一个错误。。。。
testString=“abcd”;
//这不会给我一个错误。。。。
//整数计数=65;
//对于(int i=0;i<5;i++)
//{
//testString[i]=count+i;
//}
printf(“打印字符…\n”);
对于(int i=0;i<5;i++)
{
printf(“字符为:%c\n”,testString[i]);
}
printf(“释放内存…\n”);
free(testString);
//printf(“释放后访问>>%c此行:
testString = "abcd";
将调用malloc()
给出的指针与字符串文本地址重叠:“abcd”
这会导致内存泄漏,因为指向已分配内存的原始指针丢失
在C语言中,复制字符串时,它“应该”由函数处理:strcpy()
和strncpy()
,这不会损坏testString
中包含的指针
strcpy( testString, "abcd" );
strncpy( testString, "abcd", strlen( "abcd" ) );
当然,一旦分配语句覆盖/破坏了指向已分配内存的指针:testString=“abcd”
,则放入testString
的新值不得传递给free()
seg故障发生在调用free()
时,而不是使用printf
将新指针错误地分配到testString时,这不是内存泄漏。通过malloc
[或此处的strdup
分配指针时,会发生内存泄漏而且没有相应的免费调用
strcpy( testString, "abcd" );
strncpy( testString, "abcd", strlen( "abcd" ) );
另外,尝试释放尚未分配的指针也是一种错误。它[可能]不会出错,但free
会抱怨
下面是您的程序的简化版本,它说明了您可以使用的一些方法:
#include <stdio.h>
#include <string.h>
#include <malloc.h>
int opt_segv;
char *temp = "abcd";
void
dostr(char *str,int modflg)
{
printf("\n");
printf("dostr: %s\n",str);
if (modflg)
str[modflg] = 'm';
printf("dostr: %s\n",str);
}
void
test1(void)
{
int len;
char *testString;
len = strlen(temp);
testString = malloc(len + 1);
strcpy(testString,temp);
dostr(testString,1);
free(testString);
}
void
test2(void)
{
char *testString;
testString = strdup(temp);
dostr(testString,2);
free(testString);
}
void
test3(void)
{
char *testString;
// passing a pointer to a string _constant_ -- do _not_ modify
testString = temp;
dostr(testString,opt_segv ? 3 : 0);
}
int
main(int argc,char **argv)
{
char *cp;
--argc;
++argv;
for (; argc > 0; --argc, ++argv) {
cp = *argv;
if (*cp != '-')
break;
switch (cp[1]) {
case 's': // generate segfault
opt_segv = 1;
break;
}
}
test1();
test2();
test3();
return 0;
}
#包括
#包括
#包括
int opt_segv;
char*temp=“abcd”;
无效的
dostr(字符*str,内部模式)
{
printf(“\n”);
printf(“dostr:%s\n”,str);
if(modflg)
str[modflg]=“m”;
printf(“dostr:%s\n”,str);
}
无效的
测试1(无效)
{
内伦;
char*testString;
len=strlen(温度);
testString=malloc(len+1);
strcpy(testString,temp);
dostr(testString,1);
free(testString);
}
无效的
测试2(无效)
{
char*testString;
testString=strdup(temp);
dostr(testString,2);
free(testString);
}
无效的
测试3(无效)
{
char*testString;
//将指针传递给字符串u常量--do u not uu modify
testString=temp;
dostr(测试字符串,opt_segv?3:0);
}
int
主(内部argc,字符**argv)
{
char*cp;
--argc;
++argv;
对于(;argc>0;--argc,++argv){
cp=*argv;
如果(*cp!='-'))
打破
交换机(cp[1]){
案例's'://生成segfault
opt_segv=1;
打破
}
}
test1();
test2();
test3();
返回0;
}
您可以使用-s
运行程序,以模拟导致segfault的字符串常量修改。包含与我的问题答案相关的内容,但没有详细的答案。@Jonathan的评论回答了我所有的问题,但他没有提出详细的答案,因此我正在编写我的答案,以便那些将还可以有详细的说明:
我创建了一个指针并在内存的“堆段”上分配了一些空间,现在我的指针指向堆上的那个内存位置。
与所有这些相关的代码是-char*testString=malloc(sizeof(char)*5);
现在,当我显示这个-testString=“abcd”
时,将在内存的“文本/代码段”(或在某些实现数据段)中创建字符串“abcd”,并返回内存地址并将其分配给指针testString
发生的情况是,原来指向堆上内存位置的指针丢失,指针开始指向内存的文本/代码段上的内存位置
这一切的含义:
- 它导致了内存泄漏,因为我原来指向堆内存的指针丢失了,所以现在我没有方法释放堆内存,从而导致内存泄漏
- 当我尝试使用
free(testString);
释放内存时,我会得到分段错误(这正是发生在我身上的情况),因为free()
只能用于释放使用malloc、calloc或realloc分配的内存。现在,由于指针testString
指向文本/代码段上的内存位置,并且我没有使用某些C内存分配方法分配该内存,因此我无法使用free()释放它
如果我这样做了,就会出现分段错误
- 如果执行
testString=“abcd”
(当testString是指针时),则无法访问testString
所指的内存位置,因为分配的内存是只读的