0

I'm trying to create a function that returns an array of strings in C. I've looked at some other questions on the site and tried some of the solutions, but nothing seems to work. I've tried (1) simply changing the function to change the array contents rather than returning it, and I've tried (2) explicitly returning the arrayz, but neither seems to work. Approach #1: In one file, the function:

 int getArray(int num, char** array)
    {
        int i;
        for (i = 0; i < num; i++)
            array[i] = "whatever";
        return 0;
    }

In another file, I call the function:

char** array = malloc(sizeof(char*) * num));
getArray(num, files);

When I try printing the contents of the array files, nothing shows up. Approach #2: In one file, the function:

 char** getArray(int num)
    {
        int i;
        char** array = malloc(sizeof(char*) * num));
        for (i = 0; i < num; i++)
            array[i] = "whatever";
        return array;
    }

In another file, I call the function:

    char** files = getArray(num);

Again, when I try printing the content of files, nothing shows up.

I have checked and the header file where getFiles() is being defined has been included in the file where I make the call. I'm not sure what's happening.

4
  • You are aware that in solution 1 you alloc to "array" but then pass "files", are you? Commented Apr 2, 2014 at 14:42
  • Due to the difference between a string literal and read from a file perhaps? Commented Apr 2, 2014 at 14:44
  • Did Eutherpy's (and my) observation solve the problem with Approach #1? If not: Do you print e.g. with printf("%s\n", array[i])? Commented Apr 2, 2014 at 14:55
  • That was a typo, the array "files" should have been "array." Commented Apr 2, 2014 at 21:55

4 Answers 4

1

You named your array "array", not "files":

char** array = malloc(sizeof(char*) * num));
getArray(num, files);

Try

getArray(num, array);
Sign up to request clarification or add additional context in comments.

Comments

0

You need to actually allocate space for your strings. You are just allocating memory for pointers to your strings. In the example you provided you can use strdup to allocate space for your whatever string. Like this:

int getArray(int num, char** array)
{
    int i;
    for (i = 0; i < num; i++)
        array[i] = strdup("whatever");
    return 0;
}

3 Comments

He doesn't need to if he just assigns an address, which is what he's doing. He may not want to create physical copies of the string.
@PeterSchneider You are correct. He does not need to in his specific case.
@user3489828 Remember to free the memory allocated by strdup with free.
0
char** array = malloc(sizeof(char*) * num));

here you allocate memory for num char pointers, but not to store num strings. you need to allocate memory for the strings too. i.e. "whatever" you are storing.
And you cant assign a string,

 array[i] = "whatever";

you should use,

strcpy(array[i],"whatever");

4 Comments

The code is fine (apart from a const issue which is irrelevant here). Of course you can assign the address of "whatever" to the pointer variable at array[i]. It's the same string in all pointers in the array though, but it's just proof of concept, I believe.
@PeterSchneider then he'll be having all pointers pointing at same string right?
Yes. [11 more characters to please SO]
Or at least pointing to dedicated static buffers / constant strings. If that changes, he should assign dynamically allocated copies.
0

I don't know what you are trying to do. But I think you just do like this.

#include <stdio.h>

char** getArray(int num)
{
  int i;
  char** array = malloc(sizeof(char*) * num);
  char* whatever = "whatever";

  for (i = 0; i < num; i++)
  {
    array[i] = whatever;
    //    array[i][0] = '0' + i;//Comment out because "whatever" is now constant that is immutable. So you can't change it.
  }
  return array;
}

main(){
  char** arr;
  int i;
  arr = getArray(10);
  for(i=0; i<10; i++)
  {
    printf("addr=%d, val=%s\n",arr[i], arr[i]);
  }
}

output:

addr=39075716, val=whatever
addr=39075716, val=whatever
addr=39075716, val=whatever
addr=39075716, val=whatever
addr=39075716, val=whatever
addr=39075716, val=whatever
addr=39075716, val=whatever
addr=39075716, val=whatever
addr=39075716, val=whatever
addr=39075716, val=whatever

Is this OK? In above case arr[i] is readonly and points just one memory space. Occasionally this is very memory efficient.

But I think you want to do like this.

#include <stdio.h>

char** getArray(int num)
{
  int i;
  char** array = malloc(sizeof(char*) * num);
  char* whatever;

  for (i = 0; i < num; i++)
  {
    whatever = malloc(sizeof(char) * (strlen("whatever")+1));
    strcpy(whatever, "whatever");//Now you can change "whatever". Because you created new readable-writable memory space by using malloc.
    array[i] = whatever;
    array[i][0] = '0' + i;//Now You can change array[i].
  }
  return array;
}

main(){
  char** arr;
  int i;
  arr = getArray(10);
  for(i=0; i<10; i++)
  {
    printf("addr=%d, val=%s\n",arr[i], arr[i]);
  }
}

output:

addr=-356501104, val=0hatever
addr=-356501088, val=1hatever
addr=-356501072, val=2hatever
addr=-356501056, val=3hatever
addr=-356501040, val=4hatever
addr=-356501024, val=5hatever
addr=-356501008, val=6hatever
addr=-356500992, val=7hatever
addr=-356500976, val=8hatever
addr=-356500960, val=9hatever

Now you can change the arr[i] because you used malloc and create memory space for the new string("xhatever").

I hope it helps. :)

Comments