2012-04-11 4 views
1

Beim Versuch, memset ein Array von Zeichen, die statisch zugewiesen wurde, aber nicht für ein Array der gleichen Länge, die mit malloc zugewiesen wurde, bekomme ich einen segfault.C - memset segfault für statisch zugewiesenes char-Array

Variablendefinitionen:

//static 
    char inBuff[IN_BUFF_LEN]; 
    //dynamic 
    char * inBuffD; 

Funktionsaufruf:

//static, cast used because char** != char (*) [n] 
    serverInit(portNum, (char**) &inBuff, &serv_addr, &sockfd) 
    //dynamic 
    serverInit(portNum, &inBuffD, &serv_addr, &sockfd) 

Verwendung in der Funktion:

memset(*inBuffAdr, 0, IN_BUFF_LEN); 

Ich vermute, dass mein Problem in der Differenz der Funktionsaufrufe ist, oder, um genau zu sein, mein unvollständiges Verständnis der Situation "char **! = char (*) [n]". Aber ich habe es schon zu lange angeklopft und kann den Wald nicht mehr von den Bäumen sehen, daher wären alle Hinweise und Ratschläge sehr willkommen.

+1

Was ist 'inBuffAdr' und wie ist es eingestellt? – NPE

+0

es ist nur eine Struktur, die woanders benutzt wird und für die Frage unwichtig ist. aber wenn du wirklich wissen willst, kann ich dir einige details geben – Zodd

Antwort

4

Senden Sie einfach inbuff (nicht ** inbuff) und dann Memset inBuffAdr und nicht * inBufAdr (Ihre anderen memset ist wahrscheinlich auch nicht arbeiten, man muss nur wissen es noch nicht)

+2

+1 für die "funktioniert auch nicht, aber du weißt es noch nicht". –

+0

Ich habe versucht, die Zeigervariable außerhalb der Funktion zu haben, aber in der Lage sein, ihren Wert bei Bedarf einzustellen, also den Doppelzeiger. Wie für das andere memset scheint es für jetzt zu arbeiten, aber ich weiß, was du meinst :) – Zodd

0

Warum nicht serverInit() definieren die folgenden übrigens:

serverInit(...., char * inBuff, ....) 

es dann rufen

serverInit(...., inBuff, ....) 

und dann in serverInit() Anruf memset() wie folgt aus:

memset(inBuff, 0, IN_BUFF_LEN); 
1

Warum benötigen Sie einen Doppel Zeiger auf Ihre serverInit() Funktion zu übergeben? Wenn die Funktion ändern kann, wohin der Zeiger zeigt, können Sie kein statisch zugeordnetes Array übergeben. Wenn die Funktion nicht ändern kann, wohin der Zeiger zeigt, benötigen Sie keinen Doppelzeiger.

Die Art der &inBuff ist Zeiger auf Array von char der Größe IN_BUFF_LEN, die aus einem char ** ganz verschieden ist. Sie haben den Compiler dazu gebracht, sich nicht zu beschweren und behaupten, Sie wüssten besser als der Compiler, was Sie tun. Verwenden Sie einen Cast wie diesen nur, wenn Sie sicher sind, dass Sie mehr als den Compiler kennen.

Ehrlich gesagt, der aktuelle Prototyp gegeben, dann würden Sie wahrscheinlich aus am besten mit:

//static 
char inBuff[IN_BUFF_LEN]; 
char *inBuffS = inBuff; 
//dynamic 
char *inBuffD; 

serverInit(portNum, &inBuffS, &serv_addr, &sockfd); 

Aber ich bin zutiefst misstrauisch, dass Sie serverInit() revidieren sollte eine einfache char * statt char ** für die zweite nehmen Streit.

+0

Begann zu sagen, dass 'char **' ist wahrscheinlich falsch in einem Kommentar, aber Sie haben mich auch geschlagen. Ich würde auch hinzufügen, dass es oft eine gute Übung ist, Array-Größeninformationen mit einem Array herumzutragen, es sei denn, Sie sind sich ziemlich sicher, dass Sie niemals seine Größe ändern wollen. Mit anderen Worten: Ändern Sie den Prototyp in 'serverInit (kurzer Port, char * buf, size_t bufsize, struct sockaddr * addr, int * fd)'. Und tatsächlich stelle ich die Notwendigkeit in Frage, dass die fd ein Zeiger ist. –

+0

@BrianMcFarland: Ich stimme dem zu, was du sagst. Wenn die Funktion 'serverInit()' das 'fd' öffnet und es an den aufrufenden Code zurückgibt, ist der Zeiger mehr oder weniger berechtigt. Wenn Sie jedoch mehrere Rückgabeparameter haben, lohnt es sich wahrscheinlich, alle in eine Struktur zu setzen, und die Funktion nimmt einfach einen Zeiger auf die Struktur und füllt die Details entsprechend aus. Ein Problem mit der Frage ist, dass wir kaum genügend Kontext haben, um eine Antwort zu geben, die hilfreich ist. –

+0

Wie ich in einem früheren Kommentar gesagt habe, ist der Doppelzeiger, weil ich den Wert des Zeigers innerhalb der Funktion ändern kann, so dass der Wert nicht überschritten würde. @ JonathanLeffler Dies sind mehrere Rückgabewerte. Ich werde sie in eine Struktur einfügen, aber das ist im Grunde nur ein Mock-up der endgültigen Funktion. Zuerst möchte ich es funktionieren lassen und später werde ich es einpacken. Was den Kontext anbelangt, habe ich befürchtet, dass es nicht viel mehr Code gibt, den ich gepostet habe, zumindest keinen, der mit dem inBuffAdr-Wert interagiert – Zodd

0

Teil Ihrer Verwirrung ist in der Annahme, dass &inBuff dereferenziert werden kann, um inBuff zu bekommen. Wenn Sie diesen einfachen Test-Programm ausführen:

#include <stdio.h> 
char inBuff[1000]; 
int main(int argc, char *argv[]) 
{ 
    printf("%p %p\n", inBuff, &inBuff); 
    return 0; 
} 

Sie werden sehen, dass es die gleiche Adresse für beide Notationen druckt. Wenn Sie versuchen, &inBuff dereferenzieren, nehmen Sie die ersten paar Bytes des Arrays als eine Adresse.

Wie andere bereits gesagt haben, sollten Sie nur einen Zeiger auf den Speicher übergeben, den Sie einstellen werden.Hoffentlich hilft Ihnen diese Antwort bei zukünftigen Debugging-Sitzungen.