Malloc инициализирует нулевой указатель - PullRequest
2 голосов
/ 22 января 2012

Привет, я столкнулся с этой ситуацией. Я использую malloc, чтобы дать мне массив из 10 указателей. Когда я вижу тестовые указатели в gdb, один из них (третий) указывает на 0x0. Иногда в коде происходит ошибка при использовании apple [2] -> string = "hello". Почему malloc делает это? Заранее спасибо за помощь.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int
main(void)
 {
  typedef struct test
    {
      char *string;
      int data;
    } test;

   test *apple[10];  // Declare an array of 10 test pointers. This line results in one of  the  pointers having a null value.
   apple[0] = malloc(sizeof(test));
   apple[0]->string = "hello";

   printf("The string is %s\n",apple[0]->string);
   printf("Size of apple[0]->data is %d\n",sizeof(apple[0]->data));
   printf("Size of tester is %d\n",sizeof(test));
   free(apple[0]);
   return 0;

 }

Я хотел посмотреть, как будет работать массив указателей. Я не собирался использовать все 10 указателей. Так нужно ли мне malloc только то, что мне нужно? Это совпадение, что третий указатель был 0x0?

Ответы [ 3 ]

4 голосов
/ 22 января 2012

Память была выделена только для первого элемента в apple, поэтому только apple[0] указывает на действительное struct test.

Чтобы выделить память для всех элементов apple:

for (int i = 0; i < sizeof(apple) / sizeof(test*); i++)
{
    apple[i] = malloc(sizeof(test));
}

Аналогичный цикл требуется для free().

test.string - это char*, поэтому указывать строковый литерал, как вы уже сделали, нормально (хотя тип должен быть const char*).Если вы хотите скопировать строку в test.string, вам необходимо malloc() пробел для копирования и free() позже.

2 голосов
/ 22 января 2012

Существуют различные подходы, в зависимости от вашей конечной цели.

Если число элементов в вашем массиве должно быть постоянным при каждом запуске программы, вам не нужно использовать указателивообще:

test apple[10]; // array with 10 instances of test

test[0].string = ...;
test[1].data = ...;

Если вы хотите использовать свой подход (с указателями, которые сейчас не нужны), вы должны malloc () каждый элемент сам по себе (как вы это сделали)с apple[0] или malloc () всего массива:

int num = 10;
test *apple = malloc(sizeof(test) * num);

// access any element here
apple[5].string = "hello!";

free(apple);
1 голос
/ 22 января 2012

Вы выделяете только один экземпляр test и назначаете его первому элементу массива:

apple[0] = malloc(sizeof(test));

Чтобы выделить все десять, вы должны сделать:

for (int i = 0; i < 10; i++) {
    apple[i] = malloc(sizeof(test));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...