0

I have created this small program to reverse a sentence. So given: a b c d

It will give: d c b a

This works fine, until I add an extra letter. If I try "a b c d e" it will fail at the last one with the error

realloc(): invalid next size: 0x0000000000602010 *

Here is the code

#define MAX_TEXT 100

#include <stdio.h>
#include <string.h> //strlen
#include <stdlib.h> //realloc


int main(int argc, char **argv) {
    char text[MAX_TEXT] = { 0 };    
    char *parts = NULL;

    printf("Insert string: ");
    fgets(text,MAX_TEXT,stdin);
    sscanf(text,"%[^\n]",text); //remove the \n


    char **reverse = NULL;
    char **extra = NULL;
    int size = 0;
    int i = 0;

    parts = strtok (text," ");
    while (parts != NULL) {

        size += ((strlen(parts)+4) * sizeof(char));
        extra = realloc(reverse,size);

        if (extra) {
            reverse = extra; 
            reverse[i++] = parts;
        }     
        else {
            printf("Error allocating memory\n");
            exit(1);
        }

        parts = strtok (NULL, " ");
    }

    while (--i >= 0) {
        printf("%s ",reverse[i]);                
    }

    printf("\n");
}

I am still newbish with using pointers let alone pointer to pointer, so any help will be great. Thanks!

Ps: I tried using valgrind and it just points that there is something wrong at the realloc but I can't understand what exactly.

UPDATED CODE:

#define MAX_TEXT 500

#include <stdio.h>
#include <string.h> //strchr
#include <stdlib.h> //realloc


int main(int argc, char **argv) {
    char text[MAX_TEXT] = { 0 };        

    printf("Insert string: ");
    fgets(text,MAX_TEXT,stdin);
    //sscanf(text,"%[^\n]",text); //remove the \n <-- Undefined behaviour :D "if copying takes place between objects that overlap, the behavior is undefined."
    char *theEnter = strchr(text,'\n');
    if (theEnter) {
        *theEnter = 0;//remove \n
    }        

    char **reverse = NULL;
    char **extra = NULL;
    char *parts = NULL;
    int size = 0;
    int i = 0;
    size_t increse_by = sizeof(char *);

    parts = strtok (text," ");
    while (parts != NULL) {

        size += increse_by; //pointer to pointer so increase by the size of new pointer
        extra = realloc(reverse,size);

        if (extra) {
            reverse = extra; 
            reverse[i++] = parts;
        }     
        else {
            printf("Error allocating memory\n");
            exit(1);
        }

        parts = strtok (NULL, " ");
    }

    while (--i >= 0) {
        printf("%s ",reverse[i]);                
    }

    printf("\n");
}

Following Charlie Burns indication I am now allocating for char *, I also removed the sscanf function and used strchr to remove \n because, as chux indicated, what I was doing was undefined behavior.

Thanks for the help :)

4

1 回答 1

2

您的 realloc 没有分配足够的空间。sizeof(char *) 在你的机器上可能是 8。下面的 realloc 将为 strlen == 1 的一部分分配 (1 + 4) * 1 = 5。这对于字符串指针来说是不够的。

尝试改变

    size += ((strlen(parts)+4) * sizeof(char));

    size += sizeof(char *);

原因是extra并且reverse是 char **。所以它们是一个指向字符串的指针数组。通过strtok() 的每个循环,该数组都会变大。strtok() 返回一个以空字符结尾的字符串。所以你不需要为此分配内存。

在这种情况下,您不需要这样做,但您也可以这样做:

reverse[i++] = strdup(parts);

如果您想将字符串 inreverse指向 in 中的字符串的副本text,而不是在其内部text

于 2013-10-18T15:38:48.123 回答