2010-04-29 9 views
2

J'ai un problème concernant malloc(). C'est étrange. Mon code est le suivant. J'utilise un générateur aléatoire pour générer des éléments pour un tableau. Le tableau est ouvert par malloc(). Si la taille du tableau est inférieure à 8192, c'est OK. Si la taille est supérieure à 8192, cela indique une erreur de segment.C++ erreur de segmentation de malloc

void random_generator(int num, int * array) { 

    srand((unsigned)time(0)); 
    int random_integer; 
    for(int index=0; index< num; index++){ 
    random_integer = (rand()%10000)+1; 
    *(array+index) = random_integer; 
    cout << index << endl; 
    } 
} 

int main() { 
    int array_size = 10000; 
    int *input_array; 
    input_array = (int*) malloc((array_size)); 
    random_generator(8192, input_array); // if the number is larger than 8192, segment fault 
    free(input_array); 
} 
+2

er ... si facile de répondre ... – chnet

+1

Avez-vous besoin spécifiquement d'utiliser des rangées de style C? –

+0

Juste une question d'expérience. Après un certain temps, vous développez un réflexe pour attendre sizeof() chaque fois que vous voyez malloc(). – Dima

Répondre

15

malloc() prend la taille en octets, pas le nombre d'éléments. La taille d'un int est typiquement de 4 octets, donc vous n'allouez réellement que suffisamment de mémoire pour 2500 entiers. Vous allouez array_size octets, alors que vous devez allouer array_size * sizeof(int) octets.

Ainsi, l'erreur sera fixé par

input_array = (int*) malloc(array_size * sizeof(int));

post-scriptum Ne supposez jamais que vous connaissez la taille d'un int ou de tout autre type de données, car il dépend de la plateforme. Utilisez toujours sizeof().

P.P.S. C'est vraiment une question C, plutôt qu'une question C++. Si vous utilisez réellement C++, vous devriez envisager d'utiliser new et delete [] au lieu de malloc() et free(), ou mieux encore d'utiliser std::vector au lieu d'un tableau, comme l'a souligné Neil.

11

Vous voulez:

input_array = (int*) malloc(array_size * sizeof(int)); 

vous pourriez envisager le plus simple:

input_array = new int[ array_size ]; 
// stuff 
delete [] input_array; 

ou même:

std::vector <int> input_array(array_size); 

et ne pas avoir à se soucier d'appeler gratuitement ou supprimer, ou sur les exceptions.

+3

Downvote intéressante là-bas - lequel de ce qui précède est-il techniquement incorrect? –

+1

Peut-être qu'ils pensaient que vous étiez un peu trop radical avec vos fonctionnalités C++ ultra-modernes ... '' – Skilldrick

+1

@Skilldrick Nah - il semble juste que l'un des clueless est éteint sur une autre folie inutile de downvoting. Astuce à l'ignorance - les scripts d'administration SO détectent ce genre de choses. –

3

L'appel malloc que vous utilisez est erroné. Vous devriez utiliser:

malloc(sizeof(int) * array_size) 

Je pense.

1

Vous allouez des octets array_size, mais vous avez besoin d'entiers array_size. Essayez d'allouer array_size * sizeof (int) octets dans malloc.

4

input_array = (int*) malloc(sizeof(int) * (array_size));

Il est parce que le malloc est param pour le nombre d'octets et int est généralement de 4 octets.

5

Voyant que son C++, vous seriez bien mieux faire ce qui suit:

int main() 
{ 
    int array_size = 8192; 
    int *input_array = new int[array_size]; 
    random_generator(array_size, input_array); 
    delete[] input_array; 
} 

Edit: ou mieux encore:

#include <vector> 

int main() 
{ 
    int array_size = 8192; 
    std::vector<int> array; 
    array.resize(array_size); 
    random_generator(array_size, &array.front()); 
} 

Et ne vous inquiétez pas, même au sujet de la désaffecter: D

1

Tout le monde a concerté l'erreur dans l'allocation dynamique.
Mais voulez-vous vraiment une allocation dynamique?

int main() { 
    int const array_size = 10000; 
    int input_array[array_size]; 
    random_generator(8192, input_array); 
}