strcpy führt zum "Debug Assertion Failed"
-
Hallo,
ich hab folgende codezeile, die keinen Fehler oder Warnung erzeugt. Aber beim debuggen trotzdem zum Absturz führt.
strcpy(pOls->pOlsParams->pSearchCommand, (char*)pEventCommand);
ziel ist es den Inhalt der Zeiger kopieren. Nur mal so erwähnt
Das kopieren der Zeiger funktioniert ohne Probleme.
pOls->pOlsParams->pSearchCommand = pEventCommand;
Danke schon mal.
-
Ist für pOls->pOlsParams->pSearchCommand Speicher reserviert?
Warum der Cast für pEventCommand?
-
ja, speicher ist allokiert.
pEventCommand ist als unsigned char deklariert, weil der Befehl in dem das Commando in pEventCommand eingelesen wird ihn so benötigt!
Ich hab inzwischen aber rausgefunden das es wohl an der destination liegt.
Ich Programmier hier auf einer Layer die meine Firma programmiert hat und dementsprechend wurde auch der strcpy in LAYER_strcpy umprogrammiert.Code von LAYER_strcpy:
LAYER_Char* LAYER_strcpy ( LAYER_Char *destination, const LAYER_Char *source ) { /* parameter check */ if( !destination ) { LAYER_assert(0); /* <- hier kommt der Absturz */ return LAYER_NULL; } if( !source ) { LAYER_assert(0); return LAYER_NULL; } return strcpy(destination, source); }
LAYER ist nur ein Platzhalter!
mfg
-
destination (die variable) ist NULL. wo wird die funktion aufgerufen und mit welchen parametern?
-
die funktion ruf ich so auf:
LAYER_strcpy(pOls->pOlsParams->pSearchCommand, (LAYER_Char*)pEventCommand);
-
dann ist psearchcommand gleich NULL.
steig mit nem debugger durch. das is doch keine huerde, oder?
-
reiser schrieb:
die funktion ruf ich so auf:
LAYER_strcpy(pOls->pOlsParams->pSearchCommand, (LAYER_Char*)pEventCommand);
Tja, und da ist pOls->pOlsParams->pSearchCommand Null. Wohl doch keinen Speicher allokiert, oder?
-
Offensichtlich ist jedoch
pOls->pOlsParams->pSearchCommand
NULL; die frage ist also wo kommt dieser Wert her?
Weiter: Der Gebrauch strcpy ist immer heikel. Man darf strcpy NUR verwenden, wenn man zeigen kann (am besten schriftlich in der Dokumentation bei nicht-trivalen Faellen), dass die Destination wirklich immer und in allen Faellen genug Speicher, hat, um die den Quellstring aufzunehmen; und wirklich nur dann.
-
Also der Speicher wird allokiert:
/* allocate memory for Ols data structure -----------------------------------------*/ pOls = (Ols*) LAYER_calloc( 1U, sizeof(Ols), OLS_ALLOC_MODNAME, "Ols_Init" );
was dann in LAYER_malloc.h und LAYER_malloc.c auf folgendes rausläuft:
LAYER_malloc.h:#define LAYER_calloc(num, size, categoryName, blockName) internLAYER_calloc(num, size) /*...*/
LAYER_malloc.c:
void* internLAYER_calloc ( LAYER_Size num, LAYER_Size size ) { /* disable lint error 421: (Warning -- Caution -- function 'calloc(unsigned int, unsigned int)' is considered dangerous [MISRA Rule 118]) */ return calloc(num, size); /*lint !e421 */ }
Ich denke mal das so die ganze struktur allokiert wird.
Ich hab diesen Teil des Codes nicht geschrieben.
Hab ich da jetzt nen Denkfehler drin?
-
Wird der Rückgabewert von LAYER_calloc() auf NULL überprüft?
Wie sieht die Struktur Ols denn aus? Kann es sein, dass pSearchCommand nur ein char* ist (was dem Namen nach logisch wäre) und kein internes Array? Dann muss man halt für pSearchCommand extra noch Speicher reservieren.
-
pOls = (Ols*) LAYER_calloc( 1U, sizeof(Ols), OLS_ALLOC_MODNAME, "Ols_Init" );
Da liegt der Hund begraben. Die Struktur p0ls enthaelt offensichtlich nur einen Pointer auf pOlsParams und der wiederrum nur einen Pointer auf pSearchCommand (ansonsten waere der -> Zugriff nicht moeglich). Was Du also mit Deinem calloc machst, ist Speicher fuer den Pointer allociert, aber nicht den Speicherbereich auf die der Pinter zeigen muss. Das wird wohl bei dieser Funktion zweimal der Fall sein muessen fuer;
p0ls->pOlsParams
und fuer
pOls->pOlsParams->pSearchCommand
Da fehlen noch zwei calloc/mallocs.
-
OK, alles so gemacht!
Also zweimal speicher allociert und was in der Variablen gespeichert.
Und bekomme jetzt:"Access Violation..."
tritt in strcat.asm auf.
-
Wie allocierst Du denn den Steicher fuer das Array genau? Wie ist das Ergebnis bei strncpy (Rueckgabewert, Crash etc.)?
-
das ging mir jetzt mal richtig auf den sack und desshalb bin ich mit erfolg auf memcpy umgestiegen.
Aber, trotzdem danke für die hilfe. Hab einiges gelernt.
MfG
-
was fuer daten wolltest du mit strcpy kopieren?
waren die auch nullterminiert, wie es sich fuer strings gehoert?
-
Ich wollte einen String kopieren.
Und die waren auch nullterminiert, hab im Speicher explizit noch mal nachgekuckt.
-
...musst du wissen, ob das so stimmt...
war an der zieladresse genug freier speicher?