0

If I created a dynamic array inside a function and insert values in it, and I want to use this array in other function, but I want its values not to be destroyed, should I declare it as a static and as an extern? If so how do I do this?

For example:

a.c

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
} 

b.c

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;
}

This is the purpose, but should I declare inside func1() static extern char *filename;? And if it's the right way, what else should I do in order for it to work?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Batman
  • 1,244
  • 2
  • 14
  • 26
  • I think the general rule to keep in mind here is that C doesn't really anything unless you tell it to. As themaestro's answer says, nothing's going to get "destroyed" here. – Cascabel Feb 06 '11 at 16:39
  • But the moment that i will get out the function, the value does not exist anymore...] – Batman Feb 06 '11 at 16:40
  • Memory allocated by malloc isn't destroyed until you call free. Sure, you can lose track of a pointer to it, but it's still there. Perhaps you've left out a part of your question: where do you want to call func1 and func2? – Cascabel Feb 06 '11 at 16:43

3 Answers3

1

DO NOT NOT NOT declare that as an extern. Using a global variable in this context is very poor style. What you want to do is pass a pointer to the filename array as an argument to func2. When you call malloc, the OS allocates for you memory on the heap which is independent of your call stack. Therefore, even when func1 returns it is still there (until you call free).

for example

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

void func2(char * filename)
{
//do stuff to filename
}
themaestro
  • 13,750
  • 20
  • 56
  • 75
  • func2(filename); inside func1 means i can use this filename with its value without losing them inside func2 ? – Batman Feb 06 '11 at 16:37
  • To clarify a bit, C and malloc don't do reference counting the way some other languages do. All you need to do is manage to not "forget" the address of the allocated block of memory. It doesn't matter how you manage to do that - you can pass the number around, put it in temporary pointer variables, return it as the return value of a function, even re-derive it from calculations. If you do "forget" the address the memory will still be used, but you won't have any way to free() it, other than automatically when your process exits. – Chris Stratton Feb 06 '11 at 16:42
  • The problem in your example here is that i need the main to call func2() not the func1() to call it.... – Batman Feb 06 '11 at 17:04
0

If you allocate memory via malloc you can simply return the pointer from your function. The allocated memory won't be released automatically. You have to use free to do that.

0

You can only use one storage class at a time - so you cannot use both static and extern to qualify a single variable.

With dynamically allocated arrays, it is crucial to know which code will release the allocated space. If you don't, you will have a memory leak. In small-scale programs, it may not 'matter' in the sense that the program will run despite leaking memory. However, in large programs, especially long-running programs (word processors, DBMS, etc), it matters crucially.

You can pass dynamically allocated arrays - or the pointer to the dynamically allocated array - to another function. If you do not want the other function to modify it, you should write the other function so it takes const SomeType *arg as the argument. The compiler will then ensure that your code does not modify the array.

Hence:

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;
}

Alternatively, but less desirably, you can make filename into a global variable. In that case, you should declare it in header.h. However, you cannot then have the compiler enforce the constraint that func2() should treat variable as a constant - one more reason not to use global variables.

See also SO 1433204 for a discussion of extern variables in C.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • When you wrote down: // Should be in a header! you've meant to put it into the specific header.h file you've wrote in your example ? – Batman Feb 06 '11 at 18:02
  • @Mosh: probably - that (`header.h`) would be the default location for the declaration of `other_file_name` in the context. However, it might be better in some other header; without the complete program, we can't be sure. It is also possible that `other_file_name` is a static variable in `a.c`, in which case of course it does not go into a header at all. The name was used in a context which requires a definition or declaration of the variable. I carefully eliminated the undefined variable or constant `SIZE`; I defined a variable `N` too. – Jonathan Leffler Feb 06 '11 at 18:12