migf1 Δημοσ. 27 Ιουλίου 2011 Δημοσ. 27 Ιουλίου 2011 Ο κώδικας της συνάρτησης: > // --------------------------------------------------------------------------------- // Function: // int *s_strarrpos(const char *haystack, const char *needle, int *n) // --------------------------------------------------------------------------------- // Return a pointer to an array of the (0 based) positions at which needle was found // inside haystack, or NULL on failure (both haystack & needle must be valid // null-terminated strings). // // The array is dynamically created inside the function, so the returned pointer to // it should be assigned to a higher level variable, which in turn should be freed // before the termination of the program. n is assigned the length of the array (or 0 // on failure). // /*** Sample Usage of the Function: #include <stdio.h> #include <string.h> #include <stdlib.h> int main( void ) { char haystack[] = "did the chicken make the egg, or the egg the chicken?"; char needle[] = "egg"; int n, *arrpos = NULL; arrpos = s_strarrpos(haystack, needle, &n); if ( !arrpos ) exit( EXIT_FAILURE ); printf("haystack:\t%s\nneedle:\t\t%s\nn = %d\narrpos:\n", haystack, needle, n); while (--n > -1) printf("\tpos #%d: %d\n", n, arrpos[n]); free( arrpos ); exit( EXIT_SUCCESS ); } ***/ int *s_strarrpos(const char *haystack, const char *needle, int *n) { if ( !haystack || !needle ) return NULL; int *arrpos = NULL, *tmp = NULL; // always use tmp for realloc const char *cp = NULL; char *pos = NULL; int lenhay = strlen(haystack); int lenneed = strlen(needle); for (cp=haystack, *n=0; (pos=strstr(cp, needle)) != NULL; (*n)++) { tmp = realloc(tmp, (*n+1) * sizeof(int) );// claim mem for 1 more slot if ( !tmp ) // realloc failed... { // cleanup & return *n = 0; // reset n if ( arrpos ) // arrpos has stuff from before.. free( arrpos ); // free'em up return NULL; } arrpos = tmp; // accept resized array arrpos[*n] = pos - haystack; // fill in the new slot if ( (cp = pos + lenneed) > haystack + lenhay ) break; } return arrpos; } Όπως γράφω και στην τεκμηρίωση της συνάρτησης, αυτό που κάνω είναι να επιστρέφω έναν δείκτη σε έναν πίνακα που περιέχει τις θέσεις στις οποίες βρέθηκε το string needle μέσα στο string haystack. Το μέγεθος του πίνακα το επαναπροσδιορίζω δυναμικά και συνεχώς μέσα στο κεντρικό loop της συνάρτησης, με την realloc() (και το επιστρέφω μέσω της παραμέτρου n) Η ερώτηση μου είναι αν στην ANSI C η χρήση της realloc() λειτουργεί εγγυημένα ως malloc() την 1η φορά που καλείται, γιατί θυμάμαι πως στην K&R δεν! EDIT-1: Διόρθωσα τον κώδικα, σύμφωνα με αυτό το ποστ (αποφυγή πιθανού memory leak) EDIT-2: Προσθήκη σχολίων για τη χρήση του βοηθητικού δείκτη: tmp
parsifal Δημοσ. 27 Ιουλίου 2011 Δημοσ. 27 Ιουλίου 2011 Από το C89 standard: 4.10.3.4 The realloc function Synopsis #include <stdlib.h> void *realloc(void *ptr, size_t size); Description The realloc function changes the size of the object pointed to by ptr to the size specified by size. The contents of the object shall be unchanged up to the lesser of the new and old sizes. If the new size is larger, the value of the newly allocated portion of the object is indeterminate. If ptr is a null pointer, the realloc function behaves like the malloc function for the specified size. Otherwise, if ptr does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been deallocated by a call to the free or realloc function, the behavior is undefined. If the space cannot be allocated, the object pointed to by ptr is unchanged. If size is zero and ptr is not a null pointer, the object it points to is freed. Returns The realloc function returns either a null pointer or a pointer to the possibly moved allocated space.
migf1 Δημοσ. 27 Ιουλίου 2011 Μέλος Δημοσ. 27 Ιουλίου 2011 Ευχαριστώ! Έφαγα το google και δεν to έβρισκα (θα παίζει ρόλο κι ότι είμαι σερί από το πρωί και μόνο... οδοντογλυφίδες δεν έχω βάλει ακόμα για να κρατήσω ανοιχτά τα μάτια μου ) Άρα είμαι καλυμμένος, ευχαριστώ και πάλι! EDIT: Χμ, μόλις διάβασα το παρακάτω στην Wikipedia... When using realloc, one should always use a temporary variable. For example void *p = malloc(orig_size);/* and later... */ void *tmp = realloc(p, big_size); if (tmp != NULL) { p = tmp; /* OK, assign new, larger storage to p */ } else { /* handle the problem somehow */ } If instead one did void *p = malloc(orig_size);/* and later... */ p = realloc(p, big_size); and if it is not possible to obtain big_size bytes of memory, then p will have value NULL and we no longer have a pointer to the memory previously allocated for p, creating a memory leak Οπότε, σε περίπτωση που κάποιος θέλει να χρησιμοποιήσει την συνάρτηση του αρχικού post, την διόρθωσα σύμφωνα με την υπόδειξη της Wikipedia.
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.