Передать динамический массив из одной функции в другую в C - PullRequest
0 голосов
/ 06 февраля 2011

Если я создал динамический массив внутри функции и вставил в него значения, и я хочу использовать этот массив в другой функции, но я хочу, чтобы его значения не уничтожались, я должен объявить его как статический и как внешний?Если да, то как мне это сделать?

Например:

ac

void func1(void)
{
    char *filename;
    file_name=(char *) malloc ((SIZE)*sizeof(char));

    strcpy(file_name , other_file_name); 
    file_name[N-1] = '\0'; 
    file_name[N-2] = 'x';

bla bla
} 

bc

void func2(void)
{
operations on file_name
}

my_main.c

#include <stdio.h>
MORE INCLUDES HERE

#include "a.h"
#include "b.h"
int main()
{

bla bla ...

return 0;
}

Это цель, но я должен объявить внутри func1 () static extern char *filename;?И если это правильный путь, что еще я должен сделать, чтобы он заработал?

Ответы [ 3 ]

1 голос
/ 06 февраля 2011

НЕ НЕ объявляйте это как extern.Использование глобальной переменной в этом контексте - очень плохой стиль.То, что вы хотите сделать, это передать указатель на массив имени файла в качестве аргумента func2.Когда вы вызываете malloc, ОС выделяет вам память в куче, которая не зависит от вашего стека вызовов.Поэтому, даже когда func1 возвращается, он все еще там (пока вы не позвоните бесплатно).

например

void func1(void)
{
char * filename;
filename = (char*)malloc((SIZE)*sizeof(char));
//do stuff
func2(filename);
}

void func2(char * filename)
{
//do stuff to filename
}
0 голосов
/ 06 февраля 2011

Вы можете использовать только один класс хранения за раз - поэтому вы не можете использовать оба static и extern для определения одной переменной.

Для динамически размещаемых массивов важно знать, какой код освободит выделенное пространство. Если вы этого не сделаете, у вас будет утечка памяти. В небольших программах это может не иметь значения в том смысле, что программа будет работать, несмотря на утечку памяти. Однако в больших программах, особенно в долго работающих программах (текстовые процессоры, СУБД и т. Д.), Это имеет решающее значение.

Вы можете передать динамически размещенные массивы - или указатель на динамически распределенный массив - другой функции. Если вы не хотите, чтобы другая функция изменяла его, вам следует написать другую функцию, чтобы она принимала const SomeType *arg в качестве аргумента. Затем компилятор гарантирует, что ваш код не изменяет массив.

Таким образом:

header.h

extern void func2(const char *filename);
extern void func1(void);

a.c

#include "header.h"
#include <stdlib.h>
#include <string.h>

extern const char *other_file_name; // Should be in a header!

void func1(void)
{
    char *filename;
    size_t N = strlen(other_file_name) + 1;
    filename = (char *)malloc(N);

    strcpy(filename, other_file_name); 
    file_name[N-1] = '\0'; 
    file_name[N-2] = 'x';

    func2(filename);
    free(filename);
} 

b.c

#include "header.h"

void func2(const char *filename)
{
    ...operations on filename...
}

main.c

#include "header.h"

int main(void)
{
    ...
    func1();
    ...
    func2("/etc/passwd");
    return 0;
}

В качестве альтернативы, но менее желательно, вы можете сделать filename глобальной переменной. В этом случае вы должны объявить это в header.h. Однако вы не можете заставить компилятор применять ограничение, согласно которому func2() должен рассматривать переменную как константу - еще одна причина не использовать глобальные переменные.

См. Также SO 1433204 для обсуждения extern переменных в C.

0 голосов
/ 06 февраля 2011

Если вы выделите память через malloc, вы можете просто вернуть указатель из вашей функции.Выделенная память не будет освобождена автоматически.Вы должны использовать free, чтобы сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...