2013-06-03 4 views
-2

Для этого кодаC: Выделяя путаницу памяти

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


int *f (int n) 
{ 
    int *ptr = malloc (sizeof (int)); 
    *ptr = n; 
    return ptr; 
} 


int main() 
{ 
    int i; 
    int **ptr = malloc (sizeof (int *)); 
    ptr[0] = f (0); 
    for (i = 0; i < 5; ++i) 
    { 
     ptr = realloc (sizeof (int *) * (i + 2)); 
     ptr[i + 1] = malloc (sizeof (int)); 
     ptr[i + 1] = f (i + 1); 
    } 
    for (i = 0; i < 5; ++i) 
    { 
     printf ("%d\n", *ptr[i]); 
     free (ptr[i]); 
    } 
    free (ptr); 
    return 0; 
} 

ли программа выделять в два раза, чем это необходимо?

+3

Да, и это также утечки памяти. –

+0

Я предполагаю, что здесь есть учебная (домашняя работа), но «valgrind --leak-check = full» может помочь здесь красиво (скомпилируйте свою программу с информацией об отладке, чтобы получить номера строк, где вы можете пропустить память). Заметьте, кстати, что ваша текущая версия программы не будет компилироваться. – Evert

+0

Что ты думаешь? И почему? –

ответ

4

Да, вам не нужен malloc в основном, так как он сразу же перезаписывается на следующей строке и вы пропускаете эту память. Это вопрос домашнего задания?

EDIT для вопроса изменить

Это теперь утечка памяти странным образом.

Первые несколько строк не протекают, но когда вы попадаете в цикл, который вы произвольно распределяете и назначаете. (В качестве первого, перераспределить принимает, как это первый arguement указатель перераспределить, поэтому вам не хватает ptr там)

Теперь вы выделения ptr быть размером 2, затем 3, затем 4 и т.д. ... вверх до 6. а потом сразу течь, что память, как вы перезаписать указатель с вызовом f()

вы могли бы написать, что все так:

int i; 
int **ptr = malloc (sizeof(int*) * 6); 
for (i = 0; i < 6; ++i) 
{ 
    ptr[i] = f(i); 
} 
for (i = 0; i < 6; ++i) 
{ 
    printf ("%d\n", *ptr[i]); 
    free (ptr[i]); 
} 
free (ptr); 
return 0; 

как и в сторону, вы должны вообще стараться не выделять память слишком часто, это относительно медленно. Если вы можете использовать стек, вы должны, а если нет, попробуйте и выделите всю необходимую вам память, вызов realloc в цикле - плохая идея, и ее следует избегать.

В этом конкретном случае вам не нужен указатель на указатель, вы могли бы просто выделить один массив из 6 целых чисел, с int* array = malloc(sizeof(int) * 6), а затем array[0] = 0;, который будет проще и лучше.

+0

Да, это вопрос домашней работы, но я упростил его –

+0

Я отредактирую, чтобы показать исходную проблему –

+0

теперь он правильно распределяет память или? –

3

Да, он выделяет в два раза необходимую память. Кроме того, значение «ptr» в основном перезаписывается возвратом «f», поэтому у вас даже нет возможности его освободить. Вы можете удалить вызов в malloc в «main»:

int main() 
{ 
    int *ptr = f (3); 
    printf ("%d\n", *ptr); 
    free (ptr); 
    return 0; 
} 
Смежные вопросы