0

I'll be honest, I'm a complete novice at c. Thus, things like malloc and realloc are alien concepts. I think I have the basics down, but I just can't quite get there 100%.

while (int args = scanf("%s", string)) {
    if (args < 0) break;
    count++;

    if (array == NULL) {
        array = (char *) malloc(strlen(string));

        if (array == NULL) {
            printf("Error allocating memory");
            exit(1);
        }
    } else {
        printf("%s %d\n", string, strlen(string));
        array = (char *) realloc(array, (sizeof(array) + strlen(string) + 1));

        if (array == NULL) {
            printf("Error allocating memory");
            free(array);
            exit(1);
        }

        printf("%lu\n", sizeof(array));
    }

    strcpy(&array[count - 1], string);
}

It's reading from terminal - cat file | ./program and is just a bunch of words of arbitrary length. I'm trying to get them all into an array (array).

Edit: I should mentino that I'm apparently trying to access memory I didn't allocated: malloc: *** error for object 0x7fe9e04039a0: incorrect checksum for freed object - object was probably modified after being freed. *** set a breakpoint in malloc_error_break to debug Segmentation fault: 11

6
  • while (int args = scanf("%s", string)) does this really compile on your system? Commented Sep 24, 2013 at 21:12
  • yeah, how would you recommend doing that? Commented Sep 24, 2013 at 21:18
  • 1
    I would first recommend to use a C compiler to compile C, you are probably using a C++ compiler. Commented Sep 24, 2013 at 21:21
  • thanks, fixed it to work with gcc instead of g++ - I didn't even realize my editor was using it. Commented Sep 24, 2013 at 21:24
  • Showing the declarations of string and array would help...this (array = (char *) malloc(strlen(string));) is probably wrong; most likely it should be array = malloc(sizeof(*array)); which avoids me having to know the type of array and still gets the answer right. If you really are allocating a char *, then you almost certainly need strlen(string)+1 to allow for the null termination byte. Your code doesn't look wholly consistent. If you need an array of strings, you need both an array of characters pointers, and the pointers to each string: char **array = 0; but… Commented Sep 24, 2013 at 21:46

2 Answers 2

2

Looks like you don't understand what pointers, strings and char*s are in C. For example, here is some description.

Here are main problems:

  1. char* is not a string type. It's pointer to a place in memory, where string data lies char-by-char and terminates with char '\0' (null terminator)
  2. Thus, strcpy just copies a bunch of chars from one place (string variable) to another. In your case, it copies them to array, starting with element count-1. So, if you read a string longer than 1 char, you lost the data. What you probably want to do is sum lengths of all preceding strings and write starting with this place.
  3. The remaining problem is consequence: you don't allocate space for null terminator during the first iteration (which causes strcpy to access non-allocated memory and probably leads to the message you see after program's termination).
Sign up to request clarification or add additional context in comments.

6 Comments

In fact, there is no string type in C, which you can freely allocate, concatenate and do different stuff as you do with String in Java or str in Python. Strings here are arrays of chars and all you can do is limited by standard library functions and pointers arithmetic.
to sum the lengths of all preceding strings, is that something like for (i = 0; i < count - 1; i++) len = strlen(array[i]) and then to write at that location is it strcpy(&array + len, string)
Nope. char* is an array of chars. If you want to write several strings to it, you can do this only by reading them one-to-one, splitting them by, for example, null chars. Like this: string\0other\0onemore\0. And the beginnings of strings will be on array[0], array[len1+1] and so on.
But there is one more way: make an array of char*. This will have type 'char**' (pointer to pointer to char). After that, you add one element to this array on each iteration. Also you allocare extra array for this particular string on each iteration, consisting of strlen+1 chars. Then you copy data from your buffer the the last array and finally store its address to your first array, which stores pointers to all strings you read.
There are strings in C, though not a string type. In C: "a string is a contiguous sequence of characters terminated by and including the first null character". In C there are pointers to a string. "A pointer to a string is a pointer to its initial (lowest addressed) character." C11 7.1.1 1
|
1

To simplify the process, I ended up going with a char ** array instead of a char * array. For each iteration of my while loop (which, by the way, is now while (scanf("%s", string) > 0) to comply with gcc standards (I had originally compiled with g++)), I realloc using count x sizeof(char *) and then I can array[count - 1] = (char *) malloc(sizeof(string + 1) finally, strcpy(array[count - 1], string)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.