2012-01-15 3 views
0

У меня есть статический указательБесплатный 2d массив. Статический указатель

static int **2dArr; 

, а затем я выделить память для 2d массива. Как я могу освободить эту память и заменить ее другим массивом?

////////////////////////////////////////////////////////////////////////// 
    void func(int **arr) { 
    int i,j,k,tmp; 
    int **destMatrix = NULL; 
destMatrix = (int**) malloc(N * sizeof(int *)); 

if ((destMatrix == NULL)) { 
    fprintf(stderr, "out of memory\n"); 
    exit(2); 
} 

for (i = 0; i < N; i++) { 
    destMatrix[i] = (int*) malloc(N * sizeof(int)); 

    if (destMatrix[i] == NULL) { 
     fprintf(stderr, "out of memory\n"); 
     exit(2); 
    } 
} 



for(i = 0; i < N; ++i) { 
    free(arr[i]); 
} 
free(arr); 
arr = NULL; 
arr = destMatrix; 

} 
    ////////////////////////////////////////////////////////////////////////// 
    int main() { 
    2dArr = (int**) malloc(N * sizeof(int *)); 
    if (2dArr== NULL) { 
    fprintf(stderr, "out of memory\n"); 
    exit(2); 
    } 


for (i = 0; i < N; i++) { 
    2dArr[i] = (int*) malloc(N * sizeof(int)); 

    if (2dArr[i] == NULL) { 
      fprintf(stderr, "out of memory\n"); 
      exit(2); 
    } 
} 
    func(2dArr); 
    // try to print new array, access violation 
} 

Я освобождаю память и пытаюсь заменить указатель. Но тогда у меня есть нарушение прав доступа. Как я могу сделать это правильно?

+0

Перебора и бесплатно каждый указатель во втором измерении, а затем освободить главный указателю –

+1

«I свободной памяти и попытаться заменить указатель» - вы освободить память, но вы * Не заменяйте указатель. Вы заменяете его только копию (переменная 'arr' в' func'). Исходный указатель (как бы он ни назывался, он не может быть «2dArr», это не настоящий идентификатор) остается неизменным и указывает на освобожденную память. –

ответ

2

пару вещей:

  • Вы должны передать аргумент по ссылке в FUNC: void func(int ***arr) {
  • Затем измените путь вы бесплатные вещи: free((*arr)[i]); и free(*arr);
  • и, наконец, изменить способ вы переназначаете arr: *arr = destMatrix;
  • также, do а не переменные имен, начинающиеся с числа - это не работает.
  • (также, вы имели ++i вместо i++ в для цикла в конце FUNC) это на самом деле не важно, - см комментарий ниже

Я отлаженной эти вопросы с помощью Valgrind, проверить его ,

Рабочий код ниже:

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

#define N 10 
////////////////////////////////////////////////////////////////////////// 
void func(int ***arr) { 
    int **destMatrix = NULL; 
    destMatrix = malloc(N * sizeof(int *)); 

    if ((destMatrix == NULL)) { 
    fprintf(stderr, "out of memory\n"); 
    exit(2); 
    } 

    int i; 
    for (i = 0; i < N; i++) { 
    destMatrix[i] = malloc(N * sizeof(int)); 

    if (destMatrix[i] == NULL) { 
     fprintf(stderr, "out of memory\n"); 
     exit(2); 
    } 
    } 

    for(i = 0; i < N; i++) { 
    free((*arr)[i]); 
    } 
    free(*arr); 
    *arr = destMatrix; 

} 
////////////////////////////////////////////////////////////////////////// 
int main() { 
    int **tdArr = malloc(N * sizeof(int *)); 
    if (tdArr== NULL) { 
    fprintf(stderr, "out of memory\n"); 
    exit(2); 
    } 

    int i; 
    for (i = 0; i < N; i++) { 
    tdArr[i] = malloc(N * sizeof(int)); 

    if (tdArr[i] == NULL) { 
     fprintf(stderr, "out of memory\n"); 
     exit(2); 
    } 
    } 

    func(&tdArr); 
    // try to print new array, does not get access violation 

    //assign numbers 0-99 
    int j; 
    for (i=0; i<N; i++){ 
    for (j=0; j<N; j++){ 
     tdArr[i][j] = i*10+j; 
    } 
    } 
    //print numbers 
    for (i=0; i<N; i++){ 
    for (j=0; j<N; j++){ 
     printf("%d\n", tdArr[i][j]); 
    } 
    } 

    //free internal arrays 
    for (i=0; i<N; i++){ 
    free(tdArr[i]); 
    } 
    //free outer array 
    free(tdArr); 

    return 0; 
} 
+0

Как выглядит последнее наблюдение? –

+0

@ another.anon.coward Если вы '++ i' вместо' i ++ 'in: ' for (i = 0; i devictories

+0

Nope. Вы освобождаете всех. [См. Это] (http://www.ideone.com/GaEif). Способ 'for' работает в том, что после проверки инициализации и условия тело выполняется до изменения значения. См. [This] (http://cprogramminglanguage.net/c-for-loop-statement.aspx) для получения дополнительных разъяснений. –

3

Я не совсем уверен, что вы пытаетесь сделать здесь, но имейте в виду, что заявление

arr = destMatrix; 

в func только устанавливает локальную копию указателя на destMatrix. Назад в main (и в глобальном масштабе), 2dArr (или как вы его на самом деле называли, поскольку, поскольку @nm отметил, что это не действительный идентификатор), все еще имеет свое исходное значение malloc, даже если вы успешно освободили все указатели в func , Если вы попытаетесь использовать или освободить этот указатель (или старые указатели, на которые он еще указывает [вероятность]) в другом месте, вы можете получить различные ошибки. (В этом случае, будьте счастливы вы получаете ошибки. - Вы могли бы вместо того, чтобы молча уничтожая память, что какой-то другой процесс в зависимости от) Если вы намерены изменить 2dArr в func, вам нужно объявить

void func(int ***arr); 

и назовите его

func(&2dArr); 

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

free((*arr)[i]); 
1

В func вы освободить память для статического вара 2darr, и это выглядит, как вы собираетесь установить его destMatrix, но вы только установив копию входного переменного указателя на func.

Если вы измените на void func(int **& arr), то вы можете установить 2darr, это передача int ** по ссылке вместо значения.