2016-08-20 1 views
-3

Je courais sous le code et je reçois la sortie en 8 0 4 plutôt 8 9 4. Pouvez-vous s'il vous plaît me aider à comprendre le problème avec ce code-erreur étrange tout en utilisant realloc

#include <cstdlib> 
#include <iostream> 

using namespace std; 

int main() { 
    int *p; 

    p = (int*)calloc(2, sizeof(int)); 

    *(p + 0) = 8; 
    *(p + 1) = 9; 

    p = (int*)realloc(p, 3); 

    *(p + 2) = 4; 

    for (int i = 0; i < 3; i++) 
     cout << p[i] << " "; 

    free(p); 
    p = NULL; 
} 
+0

'realloc (p, 3)' -> 'realloc (p, 3 * sizeof (int))' – BLUEPIXY

+2

1) Formatez ce bordel! 2) Ne pas spammer les tags. C'est C++, pas C. 3) Comportement indéfini. RTFM! 4) N'utilisez pas l'allocation de mémoire de type C en C++. N'utilisez pas le codage de style C en C++.Si vous voulez C, écrivez le code C! 5) Utilisez la notation de tableau, pas l'arithmétique de pointeur. Ne pas obscurcir votre code. – Olaf

+0

@Olaf: Je suis d'accord à 100%. Btw, quel est l'équivalent C++ de 'realloc()'? – chqrlie

Répondre

-2

Ok, je a obtenu le problème:

p = (int*)realloc(p, 3); 

la valeur de la taille que j'avais spécifié était 3, il aurait dû être 3 * sizeof(int)

1

The realloc function a besoin de la taille sur octets et non des éléments.

Vous devez faire

int *temp = realloc(p, 3 * sizeof(*temp)); 
if (temp == NULL) 
{ 
    // Handle error... 
} 
p = temp; 

Notez que j'utilise une variable temporaire pour le résultat de realloc. En effet, si realloc échoue, il retournera NULL et réaffectera le résultat au pointeur que vous passerez comme premier argument, puis vous perdrez le pointeur d'origine.

1

La taille spécifiée en tant qu'argument à realloc() doit être calculée en nombre d'octets. Comme vous l'avez trouvé vous-même, la solution simple est

p = (int*)realloc(p, 3 * sizeof(int)); 

Soit dit en passant, vous pouvez utiliser le type de *p au lieu de int pour éviter les incohérences potentielles si le type de p changements plus tard:

p = (int*)realloc(p, 3 * sizeof(*p)); 

Mais depuis la distribution est nécessaire en C++, l'incohérence au moins être visible. Vous devez également tester si calloc() et realloc() ont réussi. Ils ne lancent pas d'exception mais renvoient NULL en cas de mémoire insuffisante.

Notez que vous devez décider si vous programmez en C ou C++. Ces langues ont une ascendance commune, mais ont divergé considérablement et certains idiomes utilisés dans l'un sont considérés comme mauvais style dans l'autre, car des constructions plus appropriées et plus sûres sont disponibles.

Voici une version corrigée de votre programme en C:

#include <assert.h> 
#include <stdio.h> 
#include <stdlib.h> 

int main(void) { 
    int *p = calloc(2, sizeof(*p)); 
    assert(p != NULL); 

    *(p + 0) = 8; 
    *(p + 1) = 9; 

    p = realloc(p, 3 * sizeof(*p)); 
    assert(p != NULL); 

    *(p + 2) = 4; 

    for (int i = 0; i < 3; i++) { 
     printf("%d ", p[i]); 
    } 
    putchar('\n'); 
    free(p); 
    return 0; 
} 

Tout ici est C++ programme par PaulMcKenzie qui implémente la même chose, bien que l'utilisation du pointeur p est encore mal vu:

#include <vector> 
#include <iostream> 

using namespace std; 

int main() { 
    std::vector<int> pV(2); 
    int *p = pV.data(); 
    *(p + 0) = 8; 
    *(p + 1) = 9; 
    pV.resize(3); 
    p = pV.data(); 
    *(p + 2) = 4; 
    for (int i = 0; i < 3; i++) { 
     cout << p[i] << " "; 
    } 
} 

Comme vous pouvez le voir, std::vector<int>::resize() prend le nombre d'éléments, pas besoin de calculer le nombre d'octets.

En utilisant des pointeurs et arithmétique en particulier pointeur est pas une bonne pratique en C++, une version beaucoup plus simple:

#include <vector> 
#include <iostream> 

using namespace std; 

int main() { 
    std::vector<int> v(2); 
    v[0] = 8; 
    v[1] = 9; 
    v.resize(3); 
    v[2] = 4; 
    for (int i = 0; i < 3; i++) { 
     cout << v[i] << " "; 
    } 
} 

Vous pouvez également utiliser un recenseur pour l'impression.