Anko
Anko

Reputation: 87

How do I send a char* to a function and have it change the contents of the char* in C?

I have been trying and searching online for too long without any success. I've tried a lot of the suggested answers but nothing has worked for me.

I want to basically send in a char*. It can make it NULL if necessary, but would rather the function modify a char* that already has something.

Example:

char *old = "kit";
function(old){ //does stuff and writes "kat" to old}

printf("new = %s", old);

And

result: new = kat

How can I do this?

Thanks

EDIT:

What I'm currently trying:

calling_function(char *in){ 
  char **old = NULL;
  function(&old);
  printf("old in calling function is now = %s", *old);
}

function(**old){
  <does stuff to get char *another_string = "kat">
  *old = another_string;
  printf("old is now = %s ", *old);
}

And the result is:

old is now "kat"
old in calling function is now = 

and it immediately exist the system with an unspecified error exit(-1) then hangs.

Upvotes: 1

Views: 554

Answers (6)

aardvarkk
aardvarkk

Reputation: 15986

I learned something by trying to answer this question! Here's my program that does the operation:

#include <stdio.h>

void f(char* str)
{
    strcpy(str, "kat");
}

int main(void) {
    // char* str = "kit"; // Initializing like this causes a crash!

    char str[4]; // This initialization works
    strcpy(str, "kit");

    f(str);
    printf(str); // Prints "kat"

    return 0;
}

There are obvious issues with safety, but what was strange to me is that if you declare str using the commented-out line, the program crashes. I didn't realize that initializing a string literal like that gave you a pointer to read-only memory. That's very non-obvious to me, so I was confused when my little program crashed.

I think it's important to point out that fact first and foremost because it's central to why a naive solution to the problem wouldn't necessarily work. Interesting.

Upvotes: 0

Bathsheba
Bathsheba

Reputation: 234635

You can change your function prototype to

void myFunction(char** pold)

and within that function, you are free to write

*pold = "kat";

And call the function like this: myFunction(&old);

But beware; this approach has dangers:

1) You may leak memory as the previous string (i.e. what was old originally pointing to?) may be dangling.

2) *pold = "kat"; assigns read-only memory to *pold. This is because "kat" is probably added to a string literal pool on program startup by the C runtime library. Attempting to modify the string (e.g. (*pold)[0] = 'K') is undefined behaviour. Using *pold = strdup("kat"); circumvents this problem.

Upvotes: 0

Scott Mermelstein
Scott Mermelstein

Reputation: 15397

This will take an existing char * and change it. char* old = "kit";

void changingFunction( char* pointer ) {
    strcpy( pointer, "kat" );
    /* or just pointer[1] = 'a'; */
}

changingFunction(old);
printf("new = %s\n", old);

Be careful, though. Remember that you're essentially dealing with an array, and the function doesn't know the size of the array. You always want to stay within the bounds of the array.

Consequently, you should make the function more advanced:

void changingFunction( char* pointer ) {
    char * newString = "kat";
    strncpy(pointer, newString, strlen(pointer));
}

By using strncpy, you ensure that you stay within your bounds, and since you're dealing with a null terminated char*, you can use strlen to find how big your bounds are.

Upvotes: 0

Imre Kerr
Imre Kerr

Reputation: 2428

The line

char *old = "kit";

Can cause trouble because old may point to read-only memory. What you want to do is this:

char old[128]; // or however many you need
function(old){ //does stuff and writes "kat" to old // You can use sprintf for this} 

printf("new = %s", old);

Which will allocate old on the stack, where it can be modified.

Upvotes: 1

Siva Atta
Siva Atta

Reputation: 91

An example for passing integer as reference is here: Passing by reference in C

For your example, the value can be changed in the function as below:

char *old = "kit";
/* this will print kit */
printf("old = %s",old);
function(old);
/* this will print kat */
printf("updated old = %s", old); 

function(char *old) {
   *old = "kat"
}

Upvotes: 1

Jack
Jack

Reputation: 133557

A char* is nothing more an address that points to some bytes which are then interpreted as a string, how to do what you need really depends on what you need to do.

If you want to change a character of the string then a normal char* (non const) pointer will be enough:

void function(char *data) {
  data[0] = 'a';
}

If, instead, you want to replace the whole string with another one (possibly of different length), then you will need to pass the address that contains the address, so that you can directly replace it to a new address (that points to a different string):

void function(char **data) {
  *data = strdup("newstring");
  // strdup is used because a string literal must be considered as const
  // otherwise you could invoke UB by modifying the returned string
}

char *value;
function(&value);

Upvotes: 2

Related Questions