Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.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
C 尝试释放内存时出现分段错误_C_Segmentation Fault - Fatal编程技术网

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
    所指的内存位置,因为分配的内存是只读的