Изменение адреса указателя в функции - PullRequest
2 голосов
/ 26 октября 2010

Что мне нужно изменить, чтобы животное содержало {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;
}

РЕДАКТИРОВАТЬ: я вижу memcpy вариант. Есть ли другой способ манипулирования указателями?

Ответы [ 5 ]

5 голосов
/ 26 октября 2010

Есть ли другой способ просто манипулировать указателями?

Нет, потому что animal не указатель. animal это массив. Когда вы передаете его в качестве аргумента функции, он распадается на указатель на свой первый элемент, как если бы вы сказали &animal[0].

Даже если вы используете указатель и берете указатель на него в funct, он все равно не будет работать:

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

После строки с надписью "о нет!" массив fish перестает существовать; он уходит, когда funct возвращается, потому что это локальная переменная. Вы должны будете сделать его статическим или динамически распределить его, чтобы он еще существовал после возврата из функции.

Несмотря на это, оно все равно не то, что вы хотите, потому что оно никогда не модифицирует animal; изменяется только там, где animal_ptr указывает на

Если у вас есть два массива и вы хотите скопировать содержимое одного массива в другой, вам нужно использовать memcpy (или свернуть свою собственную memcpy -подобную функцию, которая копирует элементы массива в цикле или в последовательности или однако).

4 голосов
/ 26 октября 2010

Поскольку animal затухает до указателя при передаче в функцию, вы можете заменить:

elf=fish;

на:

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

или, предполагая, что они имеют одинаковый размер:

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

Редактировать сообщение вопроса:

РЕДАКТИРОВАТЬ: я вижу memcpy вариант.Есть ли другой способ просто манипулировать указателями?

Не существует безопасного способа сделать это путем манипулирования указателями, если вы имеете в виду изменение значения самого указателя.Если вы передадите указатель на указатель , вы можете изменить его так, чтобы он указывал на другое место, но, если вы укажете его на массив fish, у вас возникнут проблемы, так как он исчезнет.области видимости при выходе из funct().

Вы можете использовать указатель для передачи символов в соответствии с моим первым решением выше (elf[n] доступ к массиву эквивалентен *(elf+n) доступу указателя).

1 голос
/ 26 октября 2010
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)
}
1 голос
/ 26 октября 2010

Один из вариантов - назначить элементы по отдельности:

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

Другой вариант - использовать memcpy (для этого необходимо включить string.h):

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

memcpyпринимает в качестве параметров место назначения, источник, а затем количество байтов для копирования, в данном случае 2.

0 голосов
/ 26 октября 2010

Чтобы помочь справиться с проблемами обслуживания, вам, вероятно, лучше создать функцию, которая возвращает желаемый указатель, а затем убедиться, что вы действительно освободили память из исходного массива.

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

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

Попытка переназначить массив, объявленный с использованием синтаксиса unsigned char animal [2], вызывает проблемы, поскольку он помещает весь исходный массив в стек, и даже если компилятор позволил вам это сделать, вы закончите с кучей неиспользуемой памяти в стеке. Я не проектирую языки программирования, но это очень неправильно.

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