6

I need to get strings dynamically but as I need to get more than one string, I need to use functions. So far I wrote this (I put //**** at places i think might be wrong)

char* getstring(char *str);

int main() {

    char *str;
    strcpy(str,getstring(str));//*****
    printf("\nString: %s", str);
    return 0;
}

char* getstring(char str[]){//*****
    //this part is copy paste from my teacher lol
    char c;
    int i = 0, j = 1;
    str = (char*) malloc (sizeof(char));
    printf("Input String:\n ");
    while (c != '\n') {//as long as c is not "enter" copy to str
        c = getc(stdin);
        str = (char*)realloc(str, j * sizeof(char));
        str[i] = c;
        i++;
        j++;
    }
    str[i] = '\0';//null at the end
    printf("\nString: %s", str);
    return str;//******
}

printf in the function is working but not back in main function. I tried returning void, getting rid of *s or adding, making another str2 and tring to strcpy there or not using strcpy at all. Nothing seems to working. Am I misssing something? Or maybe this is not possible at all //Thank you so much for your answers

14
  • 6
    ask your teacher to stop casting malloc Commented Dec 24, 2016 at 18:12
  • 1
    stackoverflow.com/questions/605845/… Commented Dec 24, 2016 at 18:13
  • 3
    The memory is 1 too few for the '\0' terminator. Move j++; above the realloc line. Commented Dec 24, 2016 at 18:14
  • 2
    Consider using getline(3) if it is available on your system. Commented Dec 24, 2016 at 18:16
  • 2
    @PaulStelian the first time realloc is called j is 1 so the memory allocation changes from 1 to 1. No room for terminator, as I said. Commented Dec 24, 2016 at 18:17

4 Answers 4

4

Getting the string part can be taken from this answer. Only put a \n as input to the getline funtion.

char * p = getline('\n');

Three things :- don't cast malloc, check if malloc/realloc is successful and sizeof is not a function.

Sign up to request clarification or add additional context in comments.

2 Comments

sizeof may be not a function but does obey the syntax of a function! Just like C# typeof() builtin keyword
@PaulStelian.: yep
4

The problem is not with the function that you are using, but with the way you try copying its result into an uninitialized pointer.

Good news is that you don't have to copy - your function already allocates a string in dynamic memory, so you can copy the pointer directly:

char *str = getstring(str);

This should fix the crash. A few points to consider to make your function better:

  • main needs to free(str) when it is done in order to avoid memory leak
  • Store realloc result in a temporary pointer, and do a NULL check to handle out-of-memory situations properly

Comments

4

There are two things to take away from the lesson as it stands now:

(1) You should have one way of returning the reference to the new string, either as an argument passed by reference to the function OR as a return value; you should not be implementing both.

(2) Because the subroutine your teacher gave you allocates memory on the heap, it will be available to any part of your program and you do not have to allocate any memory yourself. You should study the difference between heap memory, global memory, and automatic (stack) memory so you understand the differences between them and know how to work with each type.

(3) Because the memory is already allocated on the heap there is no need to copy the string.

Given these facts, your code can be simplified to something like the following:

int main() {

    char *str = getstring();
    printf( "\nString: %s", str );
    return 0;
}

char* getstring(){
   .... etc

Going forward, you want to think about how you de-allocate memory in your programs. For example, in this code the string is never de-allocated. It is a good habit to think about your strategy for de-allocating any memory that you allocate.

Comments

1

Let's simplify the code a bit:

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

char* getstring()
{
    char c = 0;
    int i = 0, j = 2;
    char *str = NULL;

    if ((str = (char*) malloc(sizeof(char))) == NULL)
        return NULL;

    printf("Input String: ");
    while (c = getc(stdin)) {
        if (c == '\n') break;

        str = (char*) realloc(str, j * sizeof(char));
        str[i++] = c;
        j++;
    }
    str[i] = '\0';
    printf("getstring() String: %s\n", str);
    return str;
}

int main()
{
    char *str = getstring();
    printf("main() String: %s\n", str);
    free(str);
    return 0;
}

Then execute:

$ make teststring && ./teststring 
cc     teststring.c   -o teststring
Input String: asdfasfasdf
getstring() String: asdfasfasdf
main() String: asdfasfasdf

3 Comments

You do not seem to have taken on the earlier comments about j.
... and while (c != '\n') is undefined behaviour the first time - uninitialised .
The input character string contains a newline.

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.