0

I am having trouble with the basic principles of strings in C. I have a function:

char *editStr(char *str) {
char new[strlen(str)];
... do some editing ...
return new;
}

How would I return the array of characters called "new". As I understand, the return value of the function is a char*, which means that it is asking for a pointer to the first character of a string. Right now, I guess the problem is that I am returning a character of arrays. I tried to return a pointer to the first character in "new", but that doesn't seem to work, either. I tried "return *new[0]". My string knowledge is bad.

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
hut123
  • 445
  • 3
  • 7
  • 14

7 Answers7

2

You're returning a pointer to something you've created on the stack. You can't do that.

You need to malloc() memory from the heap and return that (and then free() it later)

char *editStr(char *str) {
    char *newArray = malloc(strlen(str) +1);
     ... do some editing ...
     return newArray;
}

EDIT: Because I forgot to add 1 for the string terminator. You could also use strdup() if you wanted to start with a copy of the original string.

Brian Roach
  • 76,169
  • 12
  • 136
  • 161
2

There are various problems here but the array/pointer issue with return new; isn't one of them.

First, you want:

char new[strlen(str) + 1];

So that you have enough room for the null terminator.

Your new is allocated on the stack so returning it will only cause grief and confusion; you'll want to:

char *new = malloc(strlen(str) + 1);

instead so that the memory is still valid when the function returns.

As far as your real question goes, an array in C is the address of the first element so your return new; is fine (subject to the stack versus heap issue noted above). C arrays decay to pointers at the drop of a hat so you don't need to worry about returning an array when the function is declared to return a pointer.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
1

Here's what I see:

  1. The word "new" is a C++ keyword. Don't use it to name a variable
  2. If you want to edit the string, edit str directly.
  3. If you need to make a copy, use malloc(strlen(str)) to allocate the extra memory.
Zach Rattner
  • 20,745
  • 9
  • 59
  • 82
0

new variable is stack allocated and you cannot return the reference of a stack variable.

char *editStr(char *str) {
     char new[strlen(str)];
     ... do some editing ...
     return new;
} // At this point, Unwinding of stack begins.
  // new is on stack and the memory allocated to it is deallocated.
  // So, the returned reference is only pointing to garbage.

Instead, you should use malloc and free it once it is done.

char *new = malloc( strlen(str) + 1 ) ; // +1 for the the termination character
Mahesh
  • 34,573
  • 20
  • 89
  • 115
0

This article describes the issue you are having an how to deal with it.

The best way to return a pointer to an array in C is like this:

char *getArr()
    {
    char *retbuf = malloc(25);
    if(retbuf == NULL)
        return NULL;
    return retbuf;
    }
0

When you create a normal C array, it will only exist inside the scope you created it in (in this case, the function editStr()) and will be destroyed as soon as you return from that function. Therefore, if you were returning the array pointer, it would become useless, and if you tried to use it, your program would most likely crash.

Instead, you should dynamically allocate arrays using malloc(). It is fairly easy to use:

 char *a = (char*) malloc(sizeof(char) * 5);

This would create an array of 5 chars that you could use, and even pass between functions. However, they do not get destructed automatically when they fall out of scope, so you need to destruct them manually using free(a) when you are done with the pointers, or else you will end up with a memory leak.

See also:

Frxstrem
  • 38,761
  • 9
  • 79
  • 119
0

If you are working in a single-threaded environment and the value is used immediately, you can make the internal buffer static and it will be available even after you exit the function:

 char *editStr(char *str) {
     static char new[strlen(str)];
     ... do some editing ...
     return new;
 }

You can also use the plain old sprintf style: pass a pointer to a buffer to the function and fill it inside.

 int editStr(char *str, char *new, int new_size) {
     ... do some editing ...
     return 0; //can return error
 }
eyalm
  • 3,366
  • 19
  • 21