eirinikp Δημοσ. 7 Μαρτίου 2008 Δημοσ. 7 Μαρτίου 2008 Καλησπέρα! Έχω δύο string και θέλω να αντιγράψω το ένα στο άλλο χωρίς τη βοήθεια της βιβλιοθήκης string.h. Γράφω αυτό: int i = 0; while( (*(source+i) ) != '\0' ) { *(dest+i) = *(source+i); } *(dest+i) = '\0'; Όμως στη γραμμή κάτω από το while πετάει το αγαπημένο σε όλους segmentation fault. Ξέρει κανείς γιατί??
Legionnaire Δημοσ. 8 Μαρτίου 2008 Δημοσ. 8 Μαρτίου 2008 Έχεις δεσμεύσει από πριν μνήμη για το "dest"; Και πόση; Ο κώδικας που μας δίνεις, όντως κάνει αυτό που λες. Αλλού είναι το λάθος λοιπόν. Επίσης φαντάζομαι ότι κάπου αλλού αυξάνεις και το "i" διαφορετικά δεν πρόκειται να τερματίσει ποτέ η while, αφού ξεκινήσει.
myle Δημοσ. 8 Μαρτίου 2008 Δημοσ. 8 Μαρτίου 2008 Καλησπέρα!Έχω δύο string και θέλω να αντιγράψω το ένα στο άλλο χωρίς τη βοήθεια της βιβλιοθήκης string.h. Γράφω αυτό: int i = 0; while( (*(source+i) ) != '\0' ) { *(dest+i) = *(source+i); } *(dest+i) = '\0'; Όμως στη γραμμή κάτω από το while πετάει το αγαπημένο σε όλους segmentation fault. Ξέρει κανείς γιατί?? > int i = 0; while (source[i]) // einai to idio me source[i] != '\0', bale o,ti sou aresei { dest[i] = source[i]; i++; } dest[i] = '\0'; Τον κώδικα δεν το έτρεξα, αλλά νομίζω φαίνεται τι είχες ξεχάσει. Την αύξηση του counter. Εννοείται πιο πριν πρέπει να έχεις δεσμεύση χώρο για το dest.
eirinikp Δημοσ. 8 Μαρτίου 2008 Μέλος Δημοσ. 8 Μαρτίου 2008 Ναι ΟΚ. Στο πραγματικο file δεν είχα ξεχάσει τον counter. Επίσης, στη main τα αρχικοποιώ ως εξής: dest = "alfa"; source = "bita"; Δηλαδή αρχικοποιούνται με το ίδιο μήκος. Τη στιγμή της ανάθεσης μέσα στο while κάτι γίνεται είτε με τη δικιά μου έκδοση, είτε με την έκδοση του myle. Τι μπορεί να γίνεται?
eirinikp Δημοσ. 8 Μαρτίου 2008 Μέλος Δημοσ. 8 Μαρτίου 2008 #include<stdio.h> #include<assert.h> void string_copy( char* dest, char* source ) { int i = 0; assert( source ); assert( dest ); while( *(source+i) ) { *(dest+i) = *(source+i); i++; } *(dest+i) = '\0'; } int main( void ) { char *dest = "dest"; char *source = "sour"; string_copy( dest, source ); printf( "%s\t%s\n", dest, source ); return 0; }
myle Δημοσ. 8 Μαρτίου 2008 Δημοσ. 8 Μαρτίου 2008 > #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> void string_copy( char* dest, char* source, int size ) { int i = 0; assert( source ); assert( dest ); while (source[i] && i < size) // einai to idio me source[i] != '\0', bale o,ti sou aresei { dest[i] = source[i]; i++; } dest[i] = '\0'; } int main( void ) { char *dest; dest = malloc(sizeof("dest")); strncpy(dest, "dest", sizeof("dest")); char *source; source = malloc(sizeof("sour")); strncpy(source, "sour", sizeof("sour")); string_copy(dest, source, strlen(source) ); printf("%s\t%s\n", dest, source ); return 0; }
eirinikp Δημοσ. 8 Μαρτίου 2008 Μέλος Δημοσ. 8 Μαρτίου 2008 > strncpy(dest, "dest", sizeof("dest")); } Ευχαριστώ πολύ αλλά το νόημα είναι να μη χρησιμοποιήσω καθόλου την string.h... Το strlen άστο, το έχω υλοποιήσει οπότε ουσιαστικά από την string.h έστω ότι χρησιμοποιούμε μόνο την strlen.
warchief Δημοσ. 8 Μαρτίου 2008 Δημοσ. 8 Μαρτίου 2008 Edited: Ακυρο χρησιμοποίησα την memcpy που ειναι και αυτη στο string.h, νομιζα οτι δεν ήταν εκει...
Legionnaire Δημοσ. 8 Μαρτίου 2008 Δημοσ. 8 Μαρτίου 2008 Δεν ξέρω αν ξέρεις την malloc αλλά θα πρέπει να την χρησιμοποιήσεις. Οι δηλώσεις >char *dest = "dest"; char *source = "sour"; τοποθετούν τα 2 string σε read-only περιοχή της μνήμης! Δηλαδή μπορείς να τυπώσεις το περιεχόμενό τους αλλά ΔΕΝ μπορείς να το αλλάξεις! Για αυτό τρως segmentation. Δεν φταίει η while. Για παράδειγμα δοκίμασε το παρακάτω: > #include <stdio.h> int main (void) { char *dest = "dest"; *dest = 'A'; return 0; } Θα σου πετάξει segmentation! Η λύση είναι να δεσμεύσεις μνήμη τοπικά είτε με κάποιον στατικό πίνακα τύπου >char dest[10]; είτε με την malloc() δηλαδή >char *dest = malloc (sizeof(char) * 10); Παραθέτω μια ενδεικτική λύση στο πρόγραμμά σου: > #include <stdio.h> #include <assert.h> #include <stdlib.h> // xreiazetai gia thn malloc() void string_copy (char *dest, char *source) { int i = 0; assert (source); assert (dest); while (*(source + i)) { *(dest + i) = *(source + i); i++; } *(dest + i) = '\0'; } int main (void) { // 8elw 4 xrhsimous xarakthres + 1 gia to \0 char *dest = malloc (sizeof (char) * 5); char *source = malloc (sizeof (char) * 5); *dest = 'd'; *(dest + 1) = 'e'; *(dest + 2) = 's'; *(dest + 3) = 't'; *(dest + 4) = '\0'; *source = 's'; *(source + 1) = 'o'; *(source + 2) = 'u'; *(source + 3) = 'r'; *(source + 4) = '\0'; string_copy (dest, source); printf ("%s\t%s\n", dest, source); return 0; } Όπως βλέπεις ΔΕΝ έχω αλλάξει καθόλου την string_copy().
bokarinho Δημοσ. 8 Μαρτίου 2008 Δημοσ. 8 Μαρτίου 2008 Χμμμμ, έχεις αναρωτηθεί ποτέ αν είναι το ίδιο να πεις πχ: > char *ptrStr = "dest"; char BufPtrStr[5] = "dest"; το ένα με το άλλο; Για σκέψου το λίγο και πες μου..
eirinikp Δημοσ. 8 Μαρτίου 2008 Μέλος Δημοσ. 8 Μαρτίου 2008 Οι δηλώσεις >char *dest = "dest"; char *source = "sour"; τοποθετούν τα 2 string σε read-only περιοχή της μνήμης! Α! Αυτό δεν το είχα συνειδητοποιήσει! Ευχαριστώ! Χμμμμ, έχεις αναρωτηθεί ποτέ αν είναι το ίδιο να πεις πχ: > char *ptrStr = "dest"; char BufPtrStr[5] = "dest"; το ένα με το άλλο; Για σκέψου το λίγο και πες μου.. Αυτό ναι το ξέρω. Ο BufPtrStr δεν καταλαμβάνει θέση στη μνήμη, αλλά μόνο τα BufPtrStr [0], [1], [2] ,[3] και [4], ενώ ο ptfStr καταλαμβάνει μία θέση στη μνήμη. Αυτό που δεν ήξερα όμως ήταν αυτό που είπε ο Legionnaire. Ότι το dest θα είναι σε read only μνήμη. Ενώ το dest του BufPtrStr δε θα είναι σε read only! Σωστά? ΕΥΧΑΡΙΣΤΩ ΠΟΛΥ ΓΙΑ ΤΗ ΒΟΗΘΕΙΑ ΣΑΣ ΠΑΙΔΙΑ! ΗΤΑΝ ΠΟΛΥΤΙΜΗ!!!
eirinikp Δημοσ. 8 Μαρτίου 2008 Μέλος Δημοσ. 8 Μαρτίου 2008 Βασικά είχα γράψει άλλη μία απορία, αλλά μου λύθηκε (προς το παρόν!) Μόλις βρω και καμία άλλη (το πιθανότερο έτσι όπως έχω χαζέψει σήμερα) θα ξαναρωτήσω...
myle Δημοσ. 8 Μαρτίου 2008 Δημοσ. 8 Μαρτίου 2008 Ευχαριστώ πολύ αλλά το νόημα είναι να μη χρησιμοποιήσω καθόλου την string.h...Το strlen άστο, το έχω υλοποιήσει οπότε ουσιαστικά από την string.h έστω ότι χρησιμοποιούμε μόνο την strlen. >#include <stdio.h> #include <stdlib.h> #include <assert.h> void string_copy( char* dest, char* source, int size ) { int i = 0; assert( source ); assert( dest ); while (source[i] && i < size) // einai to idio me source[i] != '\0', bale o,ti sou aresei { dest[i] = source[i]; i++; } dest[i] = '\0'; } int main( void ) { char *dest; dest = malloc(sizeof("dest")); string_copy(dest, "dest", sizeof("dest")); char *source; source = malloc(sizeof("sour")); string_copy(source, "sour", sizeof("sour")); string_copy(dest, source, sizeof(source) ); printf("%s\t%s\n", dest, source ); return 0; } Η υλοποίηση είναι χωρίς string.h και κοντά σε αυτό που είχες σκεφθεί αρχικά. Να προτιμάς την γραφή με τις [] στους pointers γιατί κάνει πιο ευανάγνωστο το πρόγραμμα σου.
eirinikp Δημοσ. 8 Μαρτίου 2008 Μέλος Δημοσ. 8 Μαρτίου 2008 OK. Thanks, αν και το έχω υλοποιήσει ήδη. Ευχαριστώ πολύ! Υ.Γ.: Να προτιμάς την γραφή με τις [] στους pointers γιατί κάνει πιο ευανάγνωστο το πρόγραμμα σου. Το ξέρω και το προτιμάω. Όμως σε αυτή την έκδοση δεν πρέπει λέει να χρησιμοποιήσω arrays, μόνο pointers.
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.