-1
typedef struct{
  int number;
  char name[100];
} Apple

typedef struct{
  Apple *apple;
  int bit[2];
} AppleArray;

int main(){
  AppleArray *aArray;
  loadApple(&aArray);
}

loadApple(AppleArray **aArray){
  *aArray = NULL;
  for(i=0; i<100; i++){
    *aArray = realloc(*aArray, (i+1) * sizeof(AppleArray));

    /*SEGFAULT here*/
    aArray[i]->apple = NULL;

    for(j=0; j<2; j++){
      aArray[i]->apple = realloc(aArray[i]->apple, sizeof(Apple) * (j+1))
    }
  }

}

特定のサイズの AppleArray が必要です。各 AppleArray には 2 つの Apple があります。ただし、aArray[i]->apple に NULL を割り当てると segfault が発生します。そこに何が問題なのですか?

編集 :

loadApple(AppleArray **aArray){
  *aArray = malloc(100 * sizeof(AppleArray));
  for(i=0; i<100; i++){

    /*SEGFAULT here*/
    aArray[i]->apple = NULL;

    for(j=0; j<2; j++){
      aArray[i]->apple = realloc(aArray[i]->apple, sizeof(Apple) * (j+1))
    }
  }
}
4

3 に答える 3

1

Alsが上で述べたこととは別に、ループの後、i値は100になり、アクセスしようとしていますaArray[100]が、ロジックでは(間違っていますが)メモリが割り当てられているため、配列の範囲外読み取りの問題もあります。のみまでaArray[99]

loadApple 関数は次のように書き換えることができます。

loadApple(AppleArray **aArray)
{   
   *aArray = NULL;   
   *aArray = malloc(100 * sizeof(AppleArray));

   //I have shown index as 0 here just as an example.
   (*aArray)[0].apple = NULL;      
   (*aArray)[0].apple = malloc(2 * sizeof(Apple));

}

このコードは、コードのロジックが達成しようとしているのと同じ動作も提供する必要があります。

于 2012-05-11T08:02:41.003 に答える
1

realloc()以前のメモリ割り当て関数によって返されたアドレスでのみ呼び出すことができます。そうしないと、malloc()Undefined Behaviorが返されます。calloc()

C99 標準 7.20.3.4-3: realloc 関数:

void *realloc(void *ptr, size_t size);

が null ポインターの場合ptr、realloc 関数は、指定されたサイズに対して malloc 関数のように動作します。それ以外の場合、ptr がメモリ管理関数によって以前に返されたポインターと一致しない場合、または free または realloc 関数の呼び出しによってスペースが解放された場合、動作は未定義です。

于 2012-05-11T07:48:17.710 に答える
0
<pre>
#include "stdio.h"
#include "stdlib.h"

#define MAX_SIZE 5
#define NAME_SIZE 100
#define APPLE_NUM 2

typedef struct
{
    int number;
    char name[NAME_SIZE];
}Apple;

typedef struct
{
    Apple* apple;
    int bit[2];
}AppleArray;

void printApple(AppleArray** aArray)
{
    int i;
    for (i = 0; i < MAX_SIZE; ++i)
    {
        fprintf(stderr, "%4d: bit[0] = %d, bit[1] = %d\n", i, (*aArray + i)->bit[0], (*aArray + i)->bit[1]);

        int j;
        for (j = 0; j < APPLE_NUM; ++j)
        {
            fprintf(stderr, "\tapple[%d]: number = %d, name = %s\n", 
                    j, 
                    (*aArray + i)->apple[j].number, 
                    (*aArray + i)->apple[j].name);
        }

        printf("\n");
    }
}

void loadApple(AppleArray **aArray)
{
    *aArray = NULL;
    int i;
    for(i = 0; i < MAX_SIZE; i++)
    {
        AppleArray* tmp = (AppleArray*)realloc(*aArray, (i+1) * sizeof(AppleArray));
        if (tmp != NULL)
        {
            *aArray = tmp;
        }
        else
        {
            //error
            free(*aArray);
            *aArray = NULL;
            exit(0);
        }

        /*SEGFAULT here*/
        //aArray[i]->apple = NULL;
        (*aArray + i)->apple = NULL;
        (*aArray + i)->bit[0] = i;
        (*aArray + i)->bit[1] = i + 1;

        /*
        int j;
        for (j = 0; j < 2; j++)
        {
            (*aArray + i)->apple = realloc(aArray[i]->apple, sizeof(Apple) * (j+1));
        }
        */

        (*aArray + i)->apple = (Apple*)realloc(NULL, sizeof(Apple) * APPLE_NUM);

        int j;
        for (j = 0; j < APPLE_NUM; ++j)
        {
            (*aArray + i)->apple[j].number = j;
            snprintf( (*aArray + i)->apple[j].name, NAME_SIZE, "apple_%d_%d", i, j);
        }
  }//for
}

void destroyApple(AppleArray* thiz)
{
    if (thiz == NULL)
    {
        return;
    }

    int i;
    for (i = 0; i < MAX_SIZE; ++i)
    {
        free(thiz[i].apple);
        thiz[i].apple = NULL;
    }

    free(thiz);
}

int main()
{
    AppleArray *aArray;
    loadApple(&aArray);
    printApple(&aArray);
    destroyApple(aArray);

    return 0;
}
于 2012-05-11T10:12:00.177 に答える