Question

Je suis en œuvre un algorithme diviser conquer polynôme donc je peux référence contre une mise en œuvre OpenCL, mais je ne peux pas obtenir malloc au travail. Quand je lance le programme, il alloue un tas de choses, vérifie certaines choses, envoie ensuite le size/2 à l'algorithme. Puis, quand je frappe la ligne de malloc à nouveau il recrache ceci:

malloc.c: 3096: SysMalloc: Affirmation `(old_top == (((mbinptr) (((char *) & ((av) -> bacs [((1) - 1) * 2])) - __builtin_offsetof (malloc_chunk struct, fd)))) == 0 && old_size) || ((Unsigned long) (old_size)> = (unsigned long) ((((__ builtin_offsetof (struct malloc_chunk, fd_nextsize)) + ((2 * (sizeof (size_t))) - 1)) et ~ ((2 * (sizeof (size_t))) - 1))) && ((old_top) -> taille et 0x1) && ((unsigned long) old_end & pagemask) == 0) » a échoué. Aborted

La ligne en question est:

int *mult(int size, int *a, int *b) {
    int *out,i, j, *tmp1, *tmp2, *tmp3, *tmpa1, *tmpa2, *tmpb1, *tmpb2,d, *res1, *res2;
    fprintf(stdout, "size: %d\n", size);

    out = (int *)malloc(sizeof(int) * size * 2);
}

I vérifier la taille d'un fprintf, et il est un nombre entier positif (habituellement 50 à ce moment). J'ai essayé d'appeler malloc avec un numéro ordinaire aussi bien et je reçois toujours l'erreur. Je suis juste perplexe à ce qui se passe, et rien de Google que je l'ai trouvé à ce jour est utile.

Toutes les idées ce qui se passe? J'essaie de comprendre comment compiler une version plus récente du CCG dans le cas où il est une erreur de compilation, mais je doute vraiment.

Était-ce utile?

La solution

99,9% de chances que vous avez la mémoire corrompue (sur- ou sous-coulé un tampon, écrit à un pointeur après qu'il a été libéré, appelé gratuitement deux fois sur le même pointeur, etc.)

Exécuter votre code sous Valgrind pour voir où votre programme a fait quelque chose d'incorrect.

Autres conseils

Pour vous donner une meilleure compréhension de pourquoi Dans ce cas, j'aimerais élargir @ R-samuel-klatchko réponse un peu.

Lorsque vous appelez malloc, ce qui se passe réellement est un peu plus compliqué que vous donne juste un morceau de mémoire pour jouer avec. Sous le capot, malloc conserve également des informations d'entretien de la mémoire, il vous a donné (le plus important, sa taille), de sorte que lorsque vous appelez free, il sait des choses comme la quantité de mémoire à libérer. Ces informations sont généralement conservés juste avant l'emplacement de mémoire retournée par malloc. Des informations plus exhaustives sont disponibles sur Internet ™ , mais le (très) idée de base est quelque chose comme ceci:

+------+-------------------------------------------------+
+ size |                  malloc'd memory                +
+------+-------------------------------------------------+
       ^-- location in pointer returned by malloc

Sur cette base (et simplifier les choses beaucoup), lorsque vous appelez malloc, il a besoin d'obtenir un pointeur à l'autre partie de la mémoire qui est disponible. Une manière très simple de le faire est de regarder le bit précédent de la mémoire, il a distribué, et size move octets plus bas (ou vers le haut) dans la mémoire. Avec cette mise en œuvre, vous vous retrouvez avec votre mémoire à la recherche quelque chose comme ça après l'attribution p1, p2 et p3:

+------+----------------+------+--------------------+------+----------+
+ size |                | size |                    | size |          +
+------+----------------+------+--------------------+------+----------+
       ^- p1                   ^- p2                       ^- p3

Alors, ce qui est la cause de votre erreur?

Eh bien, imaginez que votre code écrit par erreur passé la quantité de mémoire que vous avez alloué (soit parce que vous avez alloué moins que vous aviez besoin tout comme votre problème ou parce que vous utilisez les mauvaises conditions aux limites quelque part dans votre code). Dites votre code écrit tellement de données à p2 qu'il se met à écraser ce qui est dans le champ de p3 size. Lorsque vous maintenant à côté malloc d'appel, il regarderez le dernier emplacement de mémoire, il est revenu, regardez son champ de taille, passer à p3 + size puis commencer à allouer de la mémoire à partir de là. Étant donné que votre code a remplacé size, cependant, cet emplacement mémoire n'est plus après la mémoire allouée précédemment.

Inutile de dire que cela peut havoc épave! Les implémenteurs de malloc ont donc mis dans un certain nombre de « affirmations », ou les chèques, qui tentent de faire un tas de vérifier la santé mentale pour attraper ce (et d'autres questions) si elles sont sur le point de se produire. Dans votre cas, ces affirmations sont violés, et donc Abandonne malloc, vous indiquant que votre code était sur le point de faire quelque chose qu'il ne devrait vraiment pas faire.

Comme indiqué précédemment, c'est une simplification grossière, mais il suffit d'illustrer ce point. La mise en œuvre de la glibc de malloc est plus de 5k lignes, et il y a eu des quantités importantes de la recherche sur la façon de construire de bons mécanismes d'allocation de mémoire dynamique, couvrant ainsi tout dans une réponse SO n'est pas possible. Espérons que cela vous a donné un peu d'une vue de ce qui cause vraiment le problème bien!

Ma solution alternative à l'utilisation Valgrind:

Je suis très heureux parce que je viens d'aider mon debug un programme d'ami. Son programme a eu ce problème exact (malloc() causant abort), avec le même message d'erreur de GDB.

Je compilé son programme en utilisant Adresse Sanitizer avec

gcc -Wall -g3 -fsanitize=address -o new new.c
              ^^^^^^^^^^^^^^^^^^

Et puis RAN gdb new. Lorsque le programme se termine par SIGABRT causé dans une malloc() ultérieure, beaucoup d'informations utiles est imprimé:

=================================================================
==407==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6060000000b4 at pc 0x7ffffe49ed1a bp 0x7ffffffedc20 sp 0x7ffffffed3c8
WRITE of size 104 at 0x6060000000b4 thread T0
    #0 0x7ffffe49ed19  (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x5ed19)
    #1 0x8001dab in CreatHT2 /home/wsl/Desktop/hash/new.c:59
    #2 0x80031cf in main /home/wsl/Desktop/hash/new.c:209
    #3 0x7ffffe061b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #4 0x8001679 in _start (/mnt/d/Desktop/hash/new+0x1679)

0x6060000000b4 is located 0 bytes to the right of 52-byte region [0x606000000080,0x6060000000b4)
allocated by thread T0 here:
    #0 0x7ffffe51eb50 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb50)
    #1 0x8001d56 in CreatHT2 /home/wsl/Desktop/hash/new.c:55
    #2 0x80031cf in main /home/wsl/Desktop/hash/new.c:209
    #3 0x7ffffe061b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

Jetons un coup d'oeil à la sortie, en particulier la trace de la pile:

La première partie dit qu'il ya une opération d'écriture invalide à new.c:59. Cette ligne se lit

memset(len,0,sizeof(int*)*p);
             ^^^^^^^^^^^^

La seconde partie indique la mémoire que la mauvaise écriture se est passé est créé à new.c:55. Cette ligne se lit

if(!(len=(int*)malloc(sizeof(int)*p))){
                      ^^^^^^^^^^^

Voilà. Il ne m'a fallu moins d'une demi-minute pour trouver le bug qui confondu mon ami pendant quelques heures. Il a réussi à localiser l'échec, mais il est un appel malloc() ultérieure qui a échoué, sans être en mesure de repérer cette erreur dans le code précédent.

Résumer: Essayez le -fsanitize=address de GCC ou Clang. Il peut être très utile lors du débogage des problèmes de mémoire.

Vous probablement au-delà du dépassement quelque part mem alloué. alors le sw sous-jacente ne capte pas sur jusqu'à ce que vous appelez malloc

Il peut y avoir une valeur de garde qui est frappée de plein fouet par être pris malloc.

modifier ... ajouté ce pour la vérification des limites de l'aide

http: //www.lrde.epita. fr / ~ akim / CCMP / doc / bornes-checking.html

J'ai reçu le message suivant, semblable à votre celui-ci:

    program: malloc.c:2372: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 *(sizeof(size_t))) - 1)) & ~((2 *(sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long) old_end & pagemask) == 0)' failed.

a fait une erreur d'un certain appel de méthode avant, lors de l'utilisation malloc. réenregistrés le signe de façon erronée la multiplication « * » avec un « + », lors de la mise à jour du facteur après sizeof () -. opérateur sur l'ajout d'un champ à un tableau non signé char

Voici le code responsable de l'erreur dans mon cas:

    UCHAR* b=(UCHAR*)malloc(sizeof(UCHAR)+5);
    b[INTBITS]=(some calculation);
    b[BUFSPC]=(some calculation);
    b[BUFOVR]=(some calculation);
    b[BUFMEM]=(some calculation);
    b[MATCHBITS]=(some calculation);

Dans une autre méthode plus tard, je malloc à nouveau et il produit le message d'erreur ci-dessus. L'appel était (assez simple):

    UCHAR* b=(UCHAR*)malloc(sizeof(UCHAR)*50);

Pensez en utilisant le « + » - signe le 1er appel, ce qui conduit à une mauvaise calcul en combinaison avec l'initialisation immédiate du tableau après (en remplaçant la mémoire qui n'a pas été affecté au tableau), a apporté une certaine confusion la carte mémoire de malloc. par conséquent, le 2ème appel a mal tourné.

Nous avons obtenu cette erreur parce que nous avons oublié de multiplier par sizeof (int). Notez l'argument malloc (..) est un nombre d'octets, pas le nombre de mots machine ou autre.

J'étais une application de portage Visual C à gcc sur Linux et moi avons eu le même problème avec

malloc.c: 3096: SysMalloc:. Affirmation utilisant gcc sur UBUNTU 11

Je déplacé le même code à une distribution SuSE (sur un autre ordinateur) et je n'ai aucun problème.

Je soupçonne que les problèmes ne sont pas dans nos programmes, mais dans le propre libc.

Je suis le même problème, j'utilisé malloc sur n fois de plus dans une boucle pour ajouter de nouvelles données de chaîne de char *. i face au même problème, mais après avoir relâché la mémoire allouée void free() problème ont été réglés

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top