在C中动态分配内存时的段错误

时间:2011-09-08 01:39:52

标签: c

我一直在尝试在C中建立一个优先级队列 首先,我做了一些初始化工作,比如分配空间。
以下是 Initialize 例程, PriorityQueue 是一个指针。

void Initialize(int MaxElement, PriorityQueue H)
{
   if (MaxElement < MinPQSize)
     printf("Priority queue size is too small");

   if (!(H = (PriorityQueue)malloc(sizeof(struct HeapStruct))))
     printf("Out of space!!!");

   if (!(H->Elements = (ElementType *)malloc((MaxElement+1) * sizeof(ElementType))))
     printf("Out of space!!!");

   H->Capacity = MaxElement;
   H->Size = 0;

   H->Elements[0] = MinData;
}

以下是测试代码的类似方法

 int MaxElement = 15;
 PriorityQueue myHeap;
 Initialize(MaxElement, myHeap);

但是当我尝试将元素插入堆中时,会弹出分段错误。
只需从 Initialize 例程返回 PriorityQueue 指针即可解决此问题。

 PriorityQueue Initialize(int MaxElement, PriorityQueue H)
 {
   ...
   return H;
 }
 myHeap = Initialize(MaxElement, myHeap);

那么引擎盖下发生了什么?
当函数返回时没有返回值,是否调用了free()?
Thx提前!

2 个答案:

答案 0 :(得分:6)

不,即使您传入的H是指针,您也会尝试在函数内更改它(使用您的第一个malloc)。为了改变某些东西,你需要传递一个指向它的指针。在这种情况下,这意味着指针指向

void Initialize (int MaxElem, PriorityQueue *H) {
    if (MaxElem < MinPQSize)
        printf("Priority queue size is too small");

    if (!(*H = (PriorityQueue)malloc(sizeof(struct HeapStruct))))
        printf("Out of space!!!");

    if (!((*H)->Elements = (ElemType *)malloc((MaxElem+1) * sizeof(ElemType))))
        printf("Out of space!!!");

    (*H)->Capacity = MaxElem;
    (*H)->Size = 0;
    (*H)->Elements[0] = MinData;
}

如果没有额外的间接级别,你在函数中更改的H将被隔离到函数中 - 它被反射回调用者。

您可能需要考虑的其他几点:

  • 您不应该从malloc转发回报,它可以隐藏您真正想知道的某些错误。
  • 如果您的第二个malloc失败,您应该释放第一个malloc
  • 的结果
  • 如果您的malloc调用中的任何一个失败,则应该返回而不是继续,因为如果取消引用空指针,则continue将导致未定义的行为。
  • 您可能不希望从通用功能打印东西,因为这可能是一种不需要的行为。如果你必须指明一个问题,你最好把一个指示传递给调用者,让他们以自己的方式处理它。

虽然说实话,我实际上喜欢返回值的版本(不需要事先传递它,因为你明确地创建了一个 new 的东西)。这样的事情应该做:

PriorityQueue Initialize (int MaxElem) {
    PriorityQueue H;

    if (MaxElem < MinPQSize) {
        printf("Priority queue size is too small");
        return NULL;
    }

    if (!(H = malloc(sizeof(*H)))) {
        printf("Out of space!!!");
        return NULL;
    }

    if (!(H->Elements = malloc((MaxElem+1) * sizeof(ElementType)))) {
        printf("Out of space!!!");
        free (H);
        return NULL;
    }

    H->Capacity = MaxElem;
    H->Size = 0;
    H->Elements[0] = MinData;

    return H;
}

PriorityQueue myHeap = Initialize (MaxElement);

答案 1 :(得分:1)

您正在按值传递指针,请允许我说明:

char* c = 0;

void set_c(char* ptr)
{
    ptr = (char*) malloc(sizeof(char) * 10);       
}

// a copy of c is sent in, 
set_c(c);
// c doesn't point to the newly allocated data!

要正确设置,必须传递指针BY指针,如下所示:

void set_c_correctly(char** ptr)
{
   *ptr = (char*) malloc(sizeof(char) * 10);
}

// a pointer to c is passed in
set_c_correctly(&c);

// now c points to the newly allocated data