In short, is there any way I can take in a char *input into a function and modify its original memory address without using something like memcpy from string.h?

Yes, you can. Your function modifyCharArray is doing the right thing. What you are seeing is caused by that fact that

char *test = "Bad";

creates "Bad" in read only memory of the program and test points to that memory. Changing it is cause for undefined behavior.

If you want to create a modifiable string, use:

char test[] = "Bad";
Answer from R Sahu on Stack Overflow
🌐
Cprogramming
cboard.cprogramming.com › c-programming › 180130-modify-char-array-function-||-reading-lines-file.html
modify char array in function || reading lines from file
What I mean to ask is what is the rule of thumb when change is going to be made to the variable from caller and otherwise? ... 1) is copying OK? I am looking at several genes (20-50K+) It is not wise to have the destination array smaller than the source array. But you may not need an auxiliary array, e.g., I think you might want to do something like this instead: ... void trim_whitespace(char *text) { size_t len = strlen(text); if (len == 0) { return; } char *first_non_space = text; while (isspace(*first_non_space)) { ++first_non_space; } char *last_non_space = text + len - 1; while (first_non_space < last_non_space && isspace(*last_non_space)) { --last_non_space; } while (first_non_space <= last_non_space) { *text++ = *first_non_space++; } *text = '\0'; } I suggest this because:
Discussions

Modify char array passed to a function, C - Stack Overflow
I would like to concat 2 strings inside a function. However, I would like the function to modify also the destination string (char array). More on stackoverflow.com
🌐 stackoverflow.com
June 3, 2019
c - Cannot modify char array - Stack Overflow
In this time, memory is created to store the address of pointer, so the address where message point can change during execution. Then you can safely do message="bar" ... Find the answer to your question by asking. Ask question ... See similar questions with these tags. ... 0 I receive an error when trying to manipulate elements of a char array within a user defined function... More on stackoverflow.com
🌐 stackoverflow.com
Changing a character array inside a function in C - Stack Overflow
Somewhat similar problems are addressed in other stackoverflow threads (e.g. Changing an array with a function in C?, Pass and change array inside function in C, Changing array inside function in C) but for some reason, even using a pointer to the character array is not working in my case (as ... More on stackoverflow.com
🌐 stackoverflow.com
November 26, 2017
c++ - C+ how to change array of chars in function - Stack Overflow
I have this header: MvProjectQueue & operator >> (char *); And I have to write a function meeting this spec. (my function should "return" an array of chars using >> operator) I ha... More on stackoverflow.com
🌐 stackoverflow.com
Top answer
1 of 2
1

dst is allocated in main. To modify that allocation in a function, you can return the new pointer or pass a pointer to pointer. Since you return another pointer, you must pass a pointer to pointer char **dest and make a few changes in the function to accommodate that change.

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

char *my_strcat ( char **dest, const char * src) {
    char *tab = malloc ( sizeof ( char) * (strlen ( *dest) + strlen ( src) + 1));//dereference dest
    if ( NULL == tab)
        return NULL;
    strcpy ( tab, *dest);//dereference dst
    strcat ( tab, src);
    free ( *dest);//dereference dest
    *dest = malloc ( sizeof ( char) * ( strlen ( tab) + 1));//dereference dest
    strcpy ( *dest, tab);//dereference dest
    return tab;
}

int main(int argc, char **argv) {
    char *dst = NULL, *src = NULL, *r = NULL;
    src = malloc ( sizeof ( char) * 100);
    strcpy ( src, "fifty");

    dst = malloc ( sizeof ( char) * 100);
    strcpy ( dst, "four");

    r = my_strcat ( &dst, src);//use address of dst
    printf ( "%s\n", r);
    printf ( "%s\n", dst);

    free ( r);
    free ( dst);
    free ( src);

    return 0;
}
2 of 2
1

There are several problems in your code. You can use tools like valgrind, clang-tidy to help you.

Here is your code with line numbers

 1  /* -*- compile-command: "gcc prog.c; ./a.out"; -*- */
 2  #include <stdio.h>
 3  #include <stdlib.h>
 4  #include <string.h>
 5  
 6  char *my_strcat(char *dest, const char *src)
 7  {
 8    char *tab = (char *)malloc(sizeof(char) * (strlen(*dest) + strlen(src) + 1));
 9    if (NULL == tab)
10      return NULL;
11    strcpy(tab, dest);
12    strcpy(tab, src);
13    free(dest);
14    dest = (char *)malloc(sizeof(char) * (strlen(tab) + 1));
15    strcpy(dest, tab);
16    return tab;
17  }
18  
19  int main(int argc, char **argv)
20  {
21    char *dst = NULL, *src = NULL, *r = NULL;
22    int i;
23    src = malloc(sizeof(char) * 100);
24    strcpy(src, "fifty");
25  
26    dst = malloc(sizeof(char *) * 100);
27    strcpy(src, "four");
28  
29    r = my_strcat(dst, src);
30    printf("%s\n", r);
31    printf("%s\n", dst);
32  
33    free(r);
34    free(dst);
35    free(src);
36  
37    return 0;
38  }

Let's use cland-tidy to perform a static analysis:

clang-tidy-7 prog.c --

prints a bunch of messages:

8 warnings generated.
/home/picaud/Temp/prog.c:8:46: warning: 1st function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage]
  char *tab = (char *)malloc(sizeof(char) * (strlen(*dest) + strlen(src) + 1));
                                             ^
/home/picaud/Temp/prog.c:26:9: note: Storing uninitialized value
  dst = malloc(sizeof(char *) * 100);
        ^
/home/picaud/Temp/prog.c:29:7: note: Calling 'my_strcat'
  r = my_strcat(dst, src);
      ^
/home/picaud/Temp/prog.c:8:46: note: 1st function call argument is an uninitialized value
  char *tab = (char *)malloc(sizeof(char) * (strlen(*dest) + strlen(src) + 1));
                                             ^
/home/picaud/Temp/prog.c:8:53: warning: incompatible integer to pointer conversion passing 'char' to parameter of type 'const char *';

etc...

The first lines explain that dest is not initialized, you can track back it to:

26    dst = malloc(sizeof(char *) * 100);
27    strcpy(src, "four");

which is certainly a bug and have to be remplaced by

26    dst = malloc(sizeof(char *) * 100);
27    strcpy(dst, "four");

Now you can rerun clang-tidy. The first message is:

/home/picaud/Temp/prog.c:8:53: warning: incompatible integer to pointer conversion passing 'char' to parameter of type 'const char *';
remove * [clang-diagnostic-int-conversion]
  char *tab = (char *)malloc(sizeof(char) * (strlen(*dest) + strlen(src) + 1));             
                                                    ^~~~~

Which immediatly points to another bug, replace:

8     char *tab = (char *)malloc(sizeof(char) * (strlen(*dest) + strlen(src) + 1));

by

8     char *tab = (char *)malloc(sizeof(char) * (strlen(dest) + strlen(src) + 1));

you also have

/home/picaud/Temp/prog.c:26:9: warning: Result of 'malloc' is converted to a pointer of type 'char', which is incompatible with sizeof operand type 'char *' [clang-analyzer-unix.MallocSizeof]
  dst = malloc(sizeof(char *) * 100);
        ^

hence you must replace:

  dst = malloc(sizeof(char *) * 100);

by

  dst = malloc(sizeof(char) * 100);

reruning clang-tidy still shows some problems:

 /home/picaud/Temp/prog.c:27:3: note: Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
/home/picaud/Temp/prog.c:31:3: warning: Use of memory after it is freed [clang-analyzer-unix.Malloc]
  printf("%s\n", dst);
  ^
/home/picaud/Temp/prog.c:26:9: note: Memory is allocated
  dst = malloc(sizeof(char) * 100);
        ^
/home/picaud/Temp/prog.c:29:7: note: Calling 'my_strcat'
  r = my_strcat(dst, src);
      ^
/home/picaud/Temp/prog.c:9:3: note: Taking false branch
  if (NULL == tab)
  ^
/home/picaud/Temp/prog.c:13:3: note: Memory is released
  free(dest);
  ^
/home/picaud/Temp/prog.c:29:7: note: Returning; memory was released via 1st parameter
  r = my_strcat(dst, src);
      ^
/home/picaud/Temp/prog.c:31:3: note: Use of memory after it is freed
  printf("%s\n", dst);

I let you check all this. On my side following these warnings I get this new version for your code:

/* -*- compile-command: "gcc prog.c; ./a.out"; -*- */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *my_strcat(char *dest, const char *src)
{
  char *tab = (char *)malloc(sizeof(char) * (strlen(dest) + strlen(src) + 1));
  if (NULL == tab)
    return NULL;
  strcpy(tab, dest);
  strcpy(tab+strlen(dest), src);
  return tab;
}

int main(int argc, char **argv)
{
  char *dst = NULL, *src = NULL, *r = NULL;
  int i;
  src = malloc(sizeof(char) * 100);
  strcpy(src, "fifty");

  dst = malloc(sizeof(char) * 100);
  strcpy(dst, "four");

  r = my_strcat(dst, src);
  printf("%s\n", r);
  printf("%s\n", dst);

  free(r);
  free(dst);
  free(src);

  return 0;
}

when run, this code prints:

gcc prog.c; ./a.out
fourfifty
four

You can use valgrind to check that there is no memory leaks:

valgrind ./a.out 
==4023== Memcheck, a memory error detector
==4023== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4023== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==4023== Command: ./a.out
==4023== 
fourfifty
four
==4023== 
==4023== HEAP SUMMARY:
==4023==     in use at exit: 0 bytes in 0 blocks
==4023==   total heap usage: 4 allocs, 4 frees, 1,234 bytes allocated
==4023== 
==4023== All heap blocks were freed -- no leaks are possible
==4023== 
==4023== For counts of detected and suppressed errors, rerun with: -v
==4023== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Good learning!

🌐
Zhu45
zhu45.org › posts › 2018 › Sep › 26 › modify-char-in-another-function
Modify char in another function
Inside the function, we modify the content on the address 0x7fff5fbff340 by deferencing c (i.e. *c), which holds a copy of 0x7fff5fbff340. After *c = "Hello World!";, the content on the address 0x7fff5fbff340 changed to 0x100000f8e, which contains "Hello World!".
🌐
Stack Overflow
stackoverflow.com › questions › 34254646 › c-how-to-change-array-of-chars-in-function
c++ - C+ how to change array of chars in function - Stack Overflow
#include <iostream> using namespace std; class SimpleShowcaseObject { public: SimpleShowcaseObject(){}; ~SimpleShowcaseObject(){}; SimpleShowcaseObject & operator >> (char *ch) { ch = "changed"; cout << "in scope: " << ch << endl; return *this; } }; int main(void) { char *ch = new char[10]; ch = "hello"; SimpleShowcaseObject o = SimpleShowcaseObject(); cout << "original: " << ch << endl; o >> ch; cout <<"changed: " << ch << endl; delete[] ch; cin.get(); return 0; } ... You could pass an allocated char array and copy to it in your operator, but then of course the function could not control the length of the array.
Find elsewhere
🌐
Cplusplus
cplusplus.com › forum › beginner › 25942
Modifying char arrays after declaration. - C++ Forum
Your error should give you some indication of this (ERROR: Cannot convert from 'char []' to 'char' at line 8, or something like that). --Rollie ... Your problem is that you are trying to write to read-only memory. Your string "Thes is a test" is a constant char array but C++ is lenient and lets you assign its address to a non-const char*. If you want modifiable memory you need to use an array created on the stack or allocated from the free-store:
🌐
Quora
quora.com › Why-can-char-arrays-be-modified-but-not-char-pointers-in-C
Why can char arrays be modified, but not char pointers, in C++? - Quora
Answer (1 of 3): I use Plain English rather than C++, but the concepts of character arrays are similar, so maybe this will help. In Plain English, all strings (character arrays) are stored in two parts: The part on the left contains the addresses of the first and last characters in the array (wh...
Top answer
1 of 4
3

1.

name="Messi";

You can´t assign a char array with a string unless at its initialization, which is done with:

char name[]="Ronaldo";

Rather use strcpy() (Header string.h) -> strcpy(name,"Messi"); instead.

Consider that the array name needs to be capable of holding the new-assigned string + the null terminator, which is in this case provided because the string "Ronaldo" has more characters than any of the following. If that would not be the case you have to define name with an appropriate amount of characters or choose a name which is bigger than anyone else or the program would cause an overflow of data in memory.

2.

Note that the switch statement doesn´t make sense if choice is always 0 because you have never read input for choice.

Also the cases to the switch are not enclosed by { and } which should give you a compilation error.

3.

choice is initialized by a character. While this is permissible, it does not make sense in this case and confuses readers of your code. Rather use int choice = 0;


Corrected code:

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

int main(void)
{
   char name[]="Ronaldo";
    int choice=0;

    printf("Select Player\n");
    printf("1.Messi\n2.Suarez\n3.Neymar\n4.Dembele\n5.Muller\n\n");

    scanf("%d",&choice);

    switch(choice)
    {

    case 1:
            printf("\nMessi is Selected");
            strcpy(name,"Messi");

            break;


    case 2:
            printf("\nSuarez is Selected");
            strcpy(name,"Suarez");

            break;


    case 3:
            printf("\nNeymar is Selected");
            strcpy(name,"Neymar");

            break;    

    case 4:
            printf("\nDembele is Selected");
            strcpy(name,"Dembele");

            break;    


    case 5:
            printf("\nMuller is Selected");
            strcpy(name,"Muller"); 
           
            break;               

    default:
            printf("Exit");
            exit(1);
    } 

    printf("\nPlayer changed to %s",name);   
    return 0;
}

Output:

/a.out
Select Player  
1.Messi      
2.Suarez      
3.Neymar             
4.Dembele 
5.Muller 
  
2        // Input from User

Suarez is Selected               
Player changed to Suarez      
2 of 4
2

The problem is that

char name[]="Ronaldo";

gives you an array of chars. That's not what you want because an array of char doesn't allow simple assignment. For char arrays you need to use strcpy.

However - what you want is a pointer to char - like:

char* name="Ronaldo";

Then you can do simple assignments like:

char* name="Ronaldo";
printf("My player is %s\n", name);
name = "Eriksen";
printf("My player is %s\n", name);

A char-pointer can be directly assigned to point to any string literal.

Besides that you never get any user input.

And notice that switch statement has a default- like:

switch(choice)
{
    case 1:
        // do some things for input 1
    break;

    case 2:
        // do some things for input 2
    break;

    default:
        // do some things for all other values
    break;
}
🌐
Reddit
reddit.com › r/c_programming › is passing a char array into a function that accepts string literals (char *) sfe?
r/C_Programming on Reddit: Is passing a char array into a function that accepts string literals (char *) sfe?
September 8, 2022 -

Is it safe to pass char arrays as string literals into functions? Take the following function signature:

 char *fgets(char *str, int n, FILE *stream)

fgets accepts char * and not a char array? So suppose I have a char array, say char string[3], and I pass it into the the aforementioned function.

Here is a minimal example:

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


int main() {
    char string[10];
    fgets(string, 10, stdin);
    string[strcspn(string, "\n")] = 0;
    printf("%s", string);
}

Is passing in string, which is a char array, into a function, fgets in this case, that accepts string literals safe?

🌐
Cplusplus
cplusplus.com › forum › beginner › 97492
Changing characters in char array - C++ Forum
The function takes char pointer and two char variables as parameters and returns int(number of changes made in the array) So the prototype would look like following int replace(char * str, char c1, char c2); this is code I managed to get to work, although I'm sure it can be done better way.
🌐
Reddit
reddit.com › r/c_programming › help with passing and editing char* by reference inside functions?
r/C_Programming on Reddit: Help with passing and editing char* by reference inside functions?
May 22, 2025 -

Hello, I'm trying to make a simple function to remove the backslashes of a date format for homework.

#include <stdio.h>
char* changeDateFormat(char** date);

int main()
{
  char* dateToFormat = "12/2/2024";

  changeDateFormat(&dateToFormat);  
  printf("%s\n", dateToFormat);

  return 0;
}

char* changeDateFormat(char** date)
{
   size_t i = 0;
   char* aux = *date;

   while(*(aux + i) != '\0){
    if(*(aux + i) == '/'){
      *(aux + i) = '-';
    }
    i++;
   }

   return aux;
}

But when I run this, it runs int SIGSEGV. I know that when passing a pointer to char by reference, dereferecing directs to an string literal which causes undefined behaviour. But is there anyway to avoid that without allocating dynamic memory and copying the string? Thanks.

PS: I must add, that the professor is insistent that we mostly use pointers to handle strings or any arrays for that matter. If I had done it, I would have foregone that additional complication and just use an array.

Top answer
1 of 9
186

When you write a "string" in your source code, it gets written directly into the executable because that value needs to be known at compile time (there are tools available to pull software apart and find all the plain text strings in them). When you write char *a = "This is a string", the location of "This is a string" is in the executable, and the location a points to, is in the executable. The data in the executable image is read-only.

What you need to do (as the other answers have pointed out) is create that memory in a location that is not read only--on the heap, or in the stack frame. If you declare a local array, then space is made on the stack for each element of that array, and the string literal (which is stored in the executable) is copied to that space in the stack.

char a[] = "This is a string";

you can also copy that data manually by allocating some memory on the heap, and then using strcpy() to copy a string literal into that space.

char *a = malloc(256);
strcpy(a, "This is a string");

Whenever you allocate space using malloc() remember to call free() when you are finished with it (read: memory leak).

Basically, you have to keep track of where your data is. Whenever you write a string in your source, that string is read only (otherwise you would be potentially changing the behavior of the executable--imagine if you wrote char *a = "hello"; and then changed a[0] to 'c'. Then somewhere else wrote printf("hello");. If you were allowed to change the first character of "hello", and your compiler only stored it once (it should), then printf("hello"); would output cello!)

2 of 9
36

No, you cannot modify it, as the string can be stored in read-only memory. If you want to modify it, you can use an array instead e.g.

char a[] = "This is a string";

Or alternately, you could allocate memory using malloc e.g.

char *a = malloc(100);
strcpy(a, "This is a string");
free(a); // deallocate memory once you've done