尝试释放内存时出现分段错误

时间:2016-01-30 22:53:32

标签: c segmentation-fault

我有下面的代码,当我得到分段错误时,我已评论过,而不是。

最初我遇到了分段错误,然后我可能发现我可能无法初始化我的char指针位置,如public static TableCellRenderer createCellRenderer(final Vector data) { return new DefaultTableCellRenderer() { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); // use data to customize current component return c; } }; } public static void setCellRenderer(JTable table, Vector data) { // Vector data = ((DefaultTableModel) table.getModel()).getDataVector(); TableCellRenderer cellRenderer = createCellRenderer(data); table.setDefaultRenderer(Object.class, cellRenderer); } 。但我无法理解 - 为什么?

我认为"abcd"会将testString = "abcd";放在第一个内存地址,a放在第二位,依此类推......

根据我初始化内存位置的方式尝试释放内存时发生分段错误。

b

<小时/>

基于@ M.M.和@ Jonathan的评论我明白,#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); } 我的testString = "abcd";将指向一个内存位置,其中创建了字符串“abcd”,因为我没有malloc'ed它我无法释放它。此外,由于我原来的堆内存指针(我使用malloc)已经不见了,所以浪费了内存或内存。

那么,这是否意味着当我使用像testString这样的printf语句时,这也是内存泄漏?那我该怎么避免呢?循环和插入char *肯定是一个坏主意。

3 个答案:

答案 0 :(得分:1)

这一行:

testString = "abcd";

将调用malloc()给出的指针与字符串文字的地址重叠:"abcd"这会导致内存泄漏,因为指向已分配内存的原始指针会丢失。

在C中,复制字符串时,它应该&#39;由函数strcpy()strncpy()处理,不会破坏testString中包含的指针。

strcpy( testString, "abcd" );
strncpy( testString, "abcd", strlen( "abcd" ) );

当然,一旦指定内存的指针被赋值语句覆盖/销毁:testString = "abcd";,放入testString的新值不得传递给free()

调用free()时会发生seg错误,而不是错误地指定testString的新指针。

答案 1 :(得分:1)

使用printf 内存泄漏。通过malloc [或此处strdup]分配指针并且没有相应的free调用时,会发生内存泄漏。

此外,尝试释放已分配 not 的指针是另一种类型的错误。它[可能]不会发生段错误,但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;
}

您可以使用-s运行程序来模拟导致段错误的字符串常量修改。

答案 2 :(得分:1)

This question内容与我的问题的答案相关,但没有详细的答案。 @ Jonathan的评论回答了我的所有问题,但他没有提出详细的答案,所以我正在写我的答案,以便进一步访问的人可以得到详细的解释:

我创建了一个指针并在&#34;堆段&#34;上分配了一些空间。内存,现在我的指针指向堆上的内存位置 与此相关的代码是 - char* testString = malloc(sizeof(char) * 5);

现在,当我解除这个 - testString = "abcd";然后字符串&#34; abcd&#34;在&#34;文本/代码段&#34; (或在某些实现数据段中)创建内存,并返回内存地址并将其分配给我的指针testString。 /> 发生的事情是我的原始指针指向堆上的内存位置,并且指针开始指向内存的文本/代码段上的内存位置。

所有这些的含义:

  • 导致内存泄漏,因为我指向堆内存的原始指针丢失了,所以现在我无法释放堆内存因此内存泄漏。
  • 当我尝试使用free(testString);释放内存时,我会遇到分段错误( 这正是发生在我身上 )因为 free() 只能用于释放使用malloc,calloc或realloc分配的内存。现在,因为指针testString指向文本/代码段上的内存位置,并且我没有使用某种C内存分配方法分配该内存,所以我无法使用free()释放它,如果我这样做所以我得到了分段错误。
  • 当我执行testString = "abcd"时(当testString是指针时),我无法访问testString指向的内存位置,因为分配的内存在内存的文本/代码段中是只读的。因此,testString[0] = 'x'也会导致细分错误。

当我printf("hello, world")时会发生什么?:
这将创造&#34;你好,世界&#34;字符串在内存的文本/代码段中为只读。我确认它确实使用size命令在C99实现中的文本/代码段中创建。