Προς το περιεχόμενο

Μπλέχτηκαν οι δείκτες...


eirinikp

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλησπέρα!

Έχω δύο string και θέλω να αντιγράψω το ένα στο άλλο χωρίς τη βοήθεια της βιβλιοθήκης string.h.

Γράφω αυτό:

int i = 0;

while( (*(source+i) ) != '\0' ) {

*(dest+i) = *(source+i);

}

*(dest+i) = '\0';

 

Όμως στη γραμμή κάτω από το while πετάει το αγαπημένο σε όλους segmentation fault.

Ξέρει κανείς γιατί??

Δημοσ.

Έχεις δεσμεύσει από πριν μνήμη για το "dest"; Και πόση; Ο κώδικας που μας δίνεις, όντως κάνει αυτό που λες. Αλλού είναι το λάθος λοιπόν.

 

Επίσης φαντάζομαι ότι κάπου αλλού αυξάνεις και το "i" διαφορετικά δεν πρόκειται να τερματίσει ποτέ η while, αφού ξεκινήσει.

Δημοσ.
Καλησπέρα!

Έχω δύο 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.

Δημοσ.

Ναι ΟΚ. Στο πραγματικο file δεν είχα ξεχάσει τον counter. Επίσης, στη main τα αρχικοποιώ ως εξής:

dest = "alfa";

source = "bita";

Δηλαδή αρχικοποιούνται με το ίδιο μήκος.

Τη στιγμή της ανάθεσης μέσα στο while κάτι γίνεται είτε με τη δικιά μου έκδοση, είτε με την έκδοση του myle. Τι μπορεί να γίνεται?

Δημοσ.

#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;

}

Δημοσ.
>
#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;
}

Δημοσ.
>
strncpy(dest, "dest", sizeof("dest"));
}

Ευχαριστώ πολύ αλλά το νόημα είναι να μη χρησιμοποιήσω καθόλου την string.h...

Το strlen άστο, το έχω υλοποιήσει οπότε ουσιαστικά από την string.h έστω ότι χρησιμοποιούμε μόνο την strlen.

Δημοσ.

Δεν ξέρω αν ξέρεις την 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().

Δημοσ.

Χμμμμ, έχεις αναρωτηθεί ποτέ αν είναι το ίδιο να πεις πχ:

>
char *ptrStr = "dest";
char BufPtrStr[5] = "dest";

το ένα με το άλλο;

 

Για σκέψου το λίγο και πες μου..

Δημοσ.

Οι δηλώσεις

>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! Σωστά?

 

ΕΥΧΑΡΙΣΤΩ ΠΟΛΥ ΓΙΑ ΤΗ ΒΟΗΘΕΙΑ ΣΑΣ ΠΑΙΔΙΑ! ΗΤΑΝ ΠΟΛΥΤΙΜΗ!!!:-D

Δημοσ.

Βασικά είχα γράψει άλλη μία απορία, αλλά μου λύθηκε (προς το παρόν!)

Μόλις βρω και καμία άλλη (το πιθανότερο έτσι όπως έχω χαζέψει σήμερα) θα ξαναρωτήσω...

Δημοσ.
Ευχαριστώ πολύ αλλά το νόημα είναι να μη χρησιμοποιήσω καθόλου την 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 γιατί κάνει πιο ευανάγνωστο το πρόγραμμα σου.

Δημοσ.

OK. Thanks, αν και το έχω υλοποιήσει ήδη. Ευχαριστώ πολύ! :-)

 

Υ.Γ.:

Να προτιμάς την γραφή με τις [] στους pointers γιατί κάνει πιο ευανάγνωστο το πρόγραμμα σου.

Το ξέρω και το προτιμάω. Όμως σε αυτή την έκδοση δεν πρέπει λέει να χρησιμοποιήσω arrays, μόνο pointers.

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...