2 Stimmen

Ändern der Zeigeradresse in der Funktion

Was muss ich hier ändern, damit das Tier {3,4} enthält?

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: Ich sehe memcpy ist eine Option. Gibt es eine andere Möglichkeit, nur Zeiger zu manipulieren?

0 Stimmen

Außerdem gibt es doppelte Umleitung, Verweise und Makros. Und bitte, verwenden Sie mehr Leerzeichen für die Identifizierung.

0 Stimmen

Nein, das geht nicht, indem man einfach Zeiger manipuliert, und zwar aus 2 Gründen: 1) animal ist ein Array, kein Zeiger (daher kann man ihm keinen Zeiger zuweisen), und 2) der Inhalt von fish aufhören zu existieren, sobald Sie von funct Selbst wenn Sie also irgendwie auf sie verweisen würden, wären sie nicht mehr gültig, sobald die Funktion zurückkehrt.

0 Stimmen

@David Sie könnten es hacken, indem Sie Fisch als const (oder sogar static ?), so dass es auf .rdata verweist, das gültig bleibt, wenn Sie die Funktion beenden. Aber ich würde es vermeiden.

5voto

James McNellis Punkte 337231

Gibt es eine andere Möglichkeit, nur Zeiger zu manipulieren?

Nein, denn animal ist kein Zeiger. animal ist ein Array. Wenn Sie es als Argument an die Funktion übergeben, wird es zerfällt auf einen Zeiger auf sein erstes Element, so als ob Sie gesagt hätten &animal[0] .

Auch wenn Sie einen Zeiger verwenden und einen Zeiger auf ihn in funct wird es trotzdem nicht funktionieren:

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

Nach der Zeile mit der Aufschrift "Oh nein!" wird die fish Array hört auf zu existieren; es verschwindet, wenn funct zurück, weil es sich um eine lokale Variable handelt. Sie müssten sie statisch machen oder dynamisch zuweisen, damit sie nach der Rückkehr der Funktion noch existiert.

Trotzdem ist es nicht dasselbe wie das, was Sie wollen, denn es ändert sich nie animal ; es ändert sich nur dort, wo animal_ptr zeigt auf.

Wenn Sie zwei Arrays haben und den Inhalt des einen Arrays in das andere kopieren wollen, müssen Sie memcpy (oder rollen Sie Ihr eigenes memcpy -ähnliche Funktion, die Array-Elemente in einer Schleife oder nacheinander oder wie auch immer kopiert).

4voto

paxdiablo Punkte 809679

Desde animal bei der Übergabe an eine Funktion in einen Zeiger zerfällt, können Sie ersetzen:

elf=fish;

mit:

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

oder, vorausgesetzt, sie sind gleich groß:

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

Frage nachbearbeiten:

EDIT: Ich sehe, dass memcpy eine Option ist. Gibt es eine andere Möglichkeit, nur Zeiger zu manipulieren?

Es gibt keinen sicheren Weg, dies zu tun, indem manipulieren. die Zeiger, wenn Sie den Wert des Zeigers selbst ändern wollen. Wenn Sie einen Zeiger auf einen Zeiger können Sie ihn so ändern, dass er auf eine andere Stelle zeigt, aber wenn Sie ihn auf die fish Array zu verwenden, werden Sie Probleme bekommen, da es aus dem Anwendungsbereich verschwindet, wenn Sie aus funct() .

Sie können verwenden. den Zeiger zur Übertragung von Zeichen gemäß meiner ersten Lösung oben ( elf[n] Array-Zugriff ist gleichbedeutend mit *(elf+n) Zeigerzugriff).

1voto

Mark Elliot Punkte 71774

Eine Möglichkeit besteht darin, die Elemente einzeln zuzuordnen:

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

Eine weitere Möglichkeit ist die Verwendung von memcpy (was die Einbeziehung von string.h ):

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

memcpy nimmt als Parameter das Ziel, die Quelle und dann die Anzahl der zu kopierenden Bytes, in diesem Fall 2.

1voto

ruslik Punkte 14336
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)
}

0voto

Sam Skuce Punkte 1646

Um mit Wartungsproblemen umzugehen, ist es wahrscheinlich besser, eine Funktion zu erstellen, die den gewünschten Zeiger zurückgibt, und dann sicherzustellen, dass der Speicher des ursprünglichen Arrays wirklich zuerst freigegeben wird.

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

Der Versuch, ein Array, das mit der Syntax 'unsigned char animal[2]' deklariert wurde, neu zuzuweisen, birgt Probleme, da das gesamte ursprüngliche Array auf den Stack gelegt wird, und selbst wenn der Compiler dies zuließe, hätte man am Ende ein Stück unbrauchbaren Speicher auf dem Stack. Ich entwerfe keine Programmiersprachen, aber das fühlt sich sehr falsch an.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X