2

What do I need to change here so that animal contains {3,4}?

void funct(unsigned char *elf)
{
 unsigned char fish[2]={3,4};
 elf=fish;
}
int main()
{
 unsigned char animal[2]={1,2};
 funct(animal);
 return 0;
}

EDIT: I see memcpy is an option. Is there another way just manipulating pointers?

4
  • There is also double indirection, refferences and macros. And please, use more spaces for identation. Commented Oct 26, 2010 at 3:42
  • No, you can't do this just by manipulating pointers, for 2 reasons: 1) animal is an array, not a pointer (so you can't assign a pointer to it), and 2) the contents of fish cease to exist once you return from funct, so even if you were pointing to them somehow, they would cease to become valid once the function returns. Commented Oct 26, 2010 at 3:43
  • @David you could hack it by declaring fish as const (or even static?), so that it will point to .rdata that will remain valid when you exit the function. But I'd avoid it. Commented Oct 26, 2010 at 3:46
  • @ruslik it would have to be static. const just means that the value is constant, not that it's valid once the enclosing block is exited. Commented Oct 26, 2010 at 3:54

5 Answers 5

5

Is there another way just manipulating pointers?

No, because animal is not a pointer. animal is an array. When you pass it as an argument to the function, it decays to a pointer to its first element, just as if you had said &animal[0].

Even if you use a pointer and take a pointer to it in funct, it still won't work:

void funct(unsigned char** elf)
{
    unsigned char fish[2] = { 3, 4 };
    *elf = fish;  // oh no!
}

int main()
{
    unsigned char animal[2] = { 1, 2 };
    unsigned char* animal_ptr = animal;
    funct(&animal_ptr); 
}

After the line marked "oh no!" the fish array ceases to exist; it goes away when funct returns because it is a local variable. You would have to make it static or allocate it dynamically on order for it to still exist after the function returns.

Even so, it's still not the same as what you want because it doesn't ever modify animal; it only modifies where animal_ptr points to.

If you have two arrays and you want to copy the contents of one array into the other, you need to use memcpy (or roll your own memcpy-like function that copies array elements in a loop or in sequence or however).

Sign up to request clarification or add additional context in comments.

Comments

4

Since animal decays to a pointer when passed to a function, you can replace:

elf=fish;

with:

elf[0] = fish[0];        // or: *elf++ = fish[0]
elf[1] = fish[1];        //     *elf   = fish[1]

or, assuming they're the same size:

memcpy (elf, fish, sizeof (fish));

Post question edit:

EDIT: I see memcpy is an option. Is there another way just manipulating pointers?

There is no safe way to do this by manipulating the pointers if you mean changing the value of the pointer itself. If you pass in a pointer to a pointer, you can change it so that it points elsewhere but, if you point it at the fish array, you're going to get into trouble since that goes out of scope when you exit from funct().

You can use the pointer to transfer characters as per my first solution above (elf[n] array access is equivalent to *(elf+n) pointer access).

2 Comments

sizeof(fish) because elf is passed as char* and not as char[2]!
Ah, yes, silly me. Made the comment about decaying to a pointer, then totally ignored it :-) Fixed, thanks guys.
1

One option is to assign the elements individually:

void funct(unsigned char *elf){
    elf[0] = 3;
    elf[1] = 4;
}

Another option is to use memcpy (which requires including string.h):

void funct(unsigned char *elf){
    unsigned char fish[2]={3,4};
    memcpy(elf, fish, 2);
}

memcpy takes as parameters the destination, the source, and then the number of bytes to copy, in this case 2.

Comments

1
void funct(unsigned char *elf) {
    unsigned char fish[2]={3,4}; // stack variable, will dissapear after the function is exited
    // elf=fish; this one assigns to the local copy of elf, that will also dissapear when we return
    memcpy(elf, fish, sizeof(fish)); // so we have to copy values
    // careful though, because sizeof(fish) can be bigger than sizeof(elf)
}

Comments

0

To help deal with maintenance issues, you're probably better off making a function that returns the pointer you want, and then making sure you've really freed any memory from the original array first.


unsigned char * func()
{
 unsigned char * fish = malloc( sizeof(unsigned char) * 2 );
 fish[0] = 3;
 fish[1] = 4;
 return fish;
}

int main ( void ) { unsigned char * animal = malloc( sizeof(unsigned char) * 2 ); animal[0] = 1; animal[1] = 2; free( animal ); animal = func(); }

Trying to reassign an array declared using the 'unsigned char animal[2]' syntax is asking for trouble because it's put the entire original array on the stack, and even if the compiler allowed you to do that, you'd end up with a chunk of unusable memory on the stack. I don't design programming languages, but that feels very wrong.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.