008
02.04.2003, 13:09 Uhr
virtual
Sexiest Bit alive (Operator)
|
Die Speicherverletzung kommt daher, daß "HELLO WORLD" ein konstanter String ist, der nicht verändert werden darf. Dein Program sollte so nicht abstürzen:
C++: |
int main (int argc, char *argv[]) { char buffer[255]; strcpy(buffer, "HELLO WORLD"); printf ("%s", substr(buffer, 2, 4)); }
|
Deine Lösung im Letzten Post funktioniert nur zufällig: r ist eine lokale Variable; sobald du die Routine verläßt, kann der Inhalt von r (und damit der sub-String) anderweitig genutzt worden sein oder gar nicht mehr existieren. Ich habe da mal die drei eben erwähnten Lösungsmöglichkeiten kurz aufgeschrieben:
C++: |
#include <stdio.h> #include <stdlib.h>
/* Lösungsansatz 1: Der substring wird in dynamischen Speicher Angelegt. Vorteil: beliebige Stringlängen möglich Nachteil: Aufrufer muß Spoeicher freigeben */ char* substr1(const char* str, int start, int end) { int len = strlen(str); char* ptr; /* Teste Parameter auf Plausibiliät */ if (end>len) end = len; if (start>len) start = len; if (start>end || start<0 || end<0 ) return NULL;
/* erzeuge substring */ ptr = malloc(end-start+1); if (NULL == ptr) return ptr; strcpy(ptr, ""); strncat(ptr, str+start, end-start+1);
return ptr; }
/* Lösungsansatz 2: Der substring wird in static Speicher geschrieben. Vorteil: Kein free seitens der Aufrufers notwendig Nachteil: Nicht mutlithreading fähig, speicherloch */ char* substr2(const char* str, int start, int end) { int len = strlen(str); /* Die folgenden Variablen MUESSEN static sein! */ static char* ptr = NULL; static int size = 0; /* Teste Parameter auf Plausibiliät */ if (end>len) end = len; if (start>len) start = len; if (start>end || start<0 || end<0 ) return NULL; /* ggf Speicher vergrößern */ if (end-start+2>size || NULL==ptr) { char* tmp = realloc(ptr, end-start+2); if (NULL == tmp) return NULL; ptr = tmp; size = end-start+2; }
strcpy(ptr, ""); strncat(ptr, str+start, end-start+1);
return ptr; }
/* Lösungsansatz 3: Result Buffer mit übergeben Vorteil: wie 2 Nachteil: Function schlägt bei zu keinem Buffer fehl; komplizierteres Interface */ char* substr3(const char* str, int start, int end, char* result, int size) { int len = strlen(str); /* Teste Parameter auf Plausibiliät */ if (end>len) end = len; if (start>len) start = len; if (start>end || start<0 || end<0 ) return NULL; if (end-start+2>size) return NULL;
strcpy(result, ""); strncat(result, str+start, end-start+1);
return result; }
int main() { const char* str = "substring demo program";
/* Anwenden ansatz 1 */ { char* ptr = substr1(str, 1, 10); if (NULL != ptr) { printf("substr1(%s, 1, 10)=\"%s\"\n", str, ptr); free(ptr); /* unbedingt erforderlich! */ } }
/* Anwenden ansatz 2 */ { char* ptr = substr2(str, 1, 10); if (NULL != ptr) { printf("substr2(%s, 1, 10)=\"%s\"\n", str, ptr); } }
/* Anwenden ansatz 3 */ { char result[20]; char* ptr = substr3(str, 1, 10, result, sizeof(result)); if (NULL != ptr) { printf("substr3(%s, 1, 10)=\"%s\"\n", str, ptr); } } }
|
Tja. Oder man nimmt gleich C++: std::string hat schon eine methode substr. -- Gruß, virtual Quote of the Month Ich eß' nur was ein Gesicht hat (Creme 21) |