I'm trying to change the value of a string by passing its address to a function.
I get NULL as a result.I tried strcpy but it dosen't work for pointers on strings.
Code :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void changeStr (char ** tmpP){
char* test="Hello world !";
char** add=&test;
tmpP=add;
}
int main() {
char* tmp;
changeStr(&tmp);
printf("\n %s \n",tmp);
return 0;
}
result :
(NULL)
Currently the behaviour of your code is undefined as changeStr is a no-op, and you are attempting to call printf with the uninitialised variable tmp. That accounts for your (arbitrary) output. On other occasions the compiler might eat your cat.
add has automatic storage duration, and tmpP is the result of a value copy of &tmp from the caller. These assignments, although perfectly valid, are not visible to the calling function main().
The solution is to write
*tmpP = "Hello World";
as the only statement in changeStr.
You should note that tmp in main() will point to a read-only string literal.
What your doing is the mistake, tmpP=add; you thought that the add value will point to tmpP.
If you want to change the value of string passed to function, you can do in this way. I saw already #Bathseba pointed out.
Try this,
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void changeStr (char ** tmpP){
char* test;
char** add=&test;
*tmpP= "Hello world !";
}
int main() {
/* Here it has string cruel that pass to function*/
char* tmp="Cruel";
changeStr(&tmp);
printf("\n %s \n",tmp);
return 0;
}
Output:
Hello world !
What you did.
void changeStr (char ** tmpP){
char* test = "Hello world !";
char** add=&test;
tmpP=add; //<-- Here your assigning add to tmpP, it shouldn't.
}
Related
I have tried so many ways of doing this and I cannot get it to work. My setup says to use char[] but everything I've researched has no information on using that. Here is my code below
#include <stdio.h>
#include <string.h>
char[] makeString(char character,int count)
{
char finalString[count];
strcpy(finalString,character);
for(int i=1;i<=count;i++)
{
strcat(finalString,character);
}
return finalString;
}
int main() {
printf("%s\n",makeString("*",5)); }
I'm trying to create a function that returns a string of the given character count amount of times. Any help is greatly appreciated.
My apologies if this is a very simple error, I mostly code in python so C is very new to me.
There are a couple of issues, mainly on char finalString[count];
finalString is a variable created within the function, it is called a local variable. It would be destroyed after the function returns.
count as the value of the count variable is dynamically changed. Its value could not be determined during the compile stage, thus the compiler could not allocate memory space for this array. The compiling would fail.
To fix this issue.
either create this variable outside and pass it into the function. Or create the variable on the HEAP space. As the Heap space are shared across the entire program and it would not be affected by function ending.
either using a constant number or dynamically allocating a chunk of memory with malloc, calloc and etc.
Here is one demo with the full code:
// main.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* makeString(char character,int count) {
char* finalString = malloc(count+1); //dynamic allocate a chunk of space. +1 for mimic string end with an extra termination sign 0.
for(int i=0; i<count; i++) {
finalString[i] = character;
}
finalString[count] = 0; // string end signal 0
return finalString; // the memory finalString pointed to is in the HEAP space.
}
int main() {
char * p = makeString('*',5);
printf("%s\n",p);
free(p); // free up the HEAP space
return 0;
}
To compile and run the code.
gcc -Wall main.c
./a.out
The output
*****
Arrays are not a first-class type in C -- there are a lot of things you can do with other types that you can't do with arrays. In particular you cannot pass an array as a parameter to a function or return one as the return value.
Because of this restriction, if you ever declare a function with an array type for a parameter or return type, the compiler will (silently) change it into a pointer, and you'll actually be passing or returning a pointer. That is what is happening here -- the return type gets changed to char *, and you return a pointer to your local array that is going out of scope, so the pointer you end up with is dangling.
Your code doesn't compile. If you want to return an array you do char * not char []. Local variables like finalString are out of scope after the function returns.
Here are 3 ways of doing it:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *initString(char *a, char c, int n) {
memset(a, c, n);
a[n] = '\0';
return a;
}
char *makeString(char c, int n) {
char *a = malloc(n + 1);
memset(a, c, n);
a[n] = '\0';
return a;
}
int main(void) {
printf("%s\n", memset((char [6]) { 0 }, '*', 5));
char s[6];
initString(s, '*', (sizeof s / sizeof *s) - 1);
printf("%s\n", s);
char *s2 = makeString('*', 5);
printf("%s\n", s2);
free(s2);
}
The following program works fine, and I'm surprised why :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void xyz(char **value)
{
// *value = strdup("abc");
*value = "abc"; // <-- ??????????
}
int main(void)
{
char *s1;
xyz(&s1);
printf("s1 : %s \n", s1);
}
Output :
s1 : abc
My understanding was that I have to use strdup() function to allocate memory for a string in C for which I have not allocated memory. But in this case the program seems to be working fine by just assigning string value using " ", can anyone please explain ?
String literals don't exist in the ether. They reside in your programs memory and have an address.
Consequently you can assign that address to pointers. The behavior of your program is well defined, and nothing bad will happen, so long as you don't attempt to modify a literal through a pointer.
For that reason, it's best to make the compiler work for you by being const correct. Prefer to mark the pointee type as const whenever possible, and your compiler will object to modification attempts.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void xyz(char const **value)
{
*value = "abc";
}
int main(void)
{
char const *s1;
xyz(&s1);
printf("s1 : %s \n", s1);
s1[0] = 'a'; << Error on this line
}
Your program works fine because string literal "abc" are character arrays , and what actually happens while assigning a string literal to a pointer is , the compiler first creates a character array and then return the address of the first element of the array just like when we call the name of any other array.
so in your program you have passed address of a char pointer to the function xyz
and
*value = "abc";
for this statement , compiler first creates a character array in the memory and then returns its address which in turn gets stored in the char pointer.It is worth knowing that the compiler creates the char array in read only memory.Thus , the address returned refers to a const char array.Any attempt to modify its value will return it compile-time error.
You can define a string in C with char *str = "some string";, str is a pointer which points to the location of the first letter in a string.
This question already has answers here:
pass strings by reference in C
(8 answers)
Closed 7 years ago.
I'm trying to Initialize a string in Initialize then pass it to int main() for screen output, but it seems that the strings that are initialized have become corrupted.
Headers
#include<stdio.h>
#include<stdlib.h>
Initialize
void
Initialize(char* STRINGs)
{
STRINGs = malloc(sizeof(char)*5);
STRINGs = "hello" ;
printf("1: %s\n",STRING);
}
Main
int
main (char* STRINGs)
{
Initialize(STRINGs);
//The program stops working when it reaches this section
printf("2: %s",STRINGs);
return 0;
}
You can use this code to initialize the string variable
char * Initialize()
{
char* STRINGs="HELLO";
printf("1: %s\n",STRINGs);
return STRINGs;
}
int main ()
{
char *strings =Initialize();
//The program stops working when it reaches this section
printf("2: %s",strings);
return 0;
}
First, you have wrong prototype for int main (char* STRINGs), which must be either:
int main(), or
int main( int argc, char *argv[] )
How do I pass a string array from a function to main
As it stands, you can create a string inside your Initialize() then return a pointer to that string.
There are several issues in your Initialize() though.
Here's a suggestion to change:
char *
Initialize()
{
char *STRINGs = malloc(strlen("hello") + 1); // <-- malloc must include an additional space for the NULL terminator.
strcpy( STRINGs, "hello" ); // <-- NEVER use assignment for string type.
printf("1: %s\n",STRINGs);
return STRINGs;
}
Then your main() can be like this:
int main()
{
char *str = Initialize();
printf( "str = %s\n", str );
return 0;
}
NOTE: do not forget to add #include <string.h>
Here's an answer. First, when allocating memory for any variable, it must be freed or you'll get some nasty system errors at some point or at the very least, a memory leak.
In the int main(), the declaration should ideally be int main(int argc, char* argv[]).
I also recommend allocating at least one more byte of memory just in case you create a string and a function you use later on requires a null character appended to it.
I fixed your code to make it work at its bare minimum.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* Initialize(){
char* string = malloc(sizeof(char)*6);
strcpy(string,"hello");
printf("1: %s\n",string);
return string;
}
int main (int argc, char* argv[]){
char *strings=Initialize();
printf("2: %s\n",strings);
free(strings);
return 0;
}
For a shorter version of your code, I suggest this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char* argv[]){
char* strings=malloc(6);
strcpy(string,"hello");
printf("2: %s\n",strings);
free(strings);
return 0;
}
For the sake of understanding, let us suppose STRINGs of main function is a.
And STRINGs of initialize function is b.
At first, in main a is pointing to some unknown location say u. When you pass this to the initialize function then b also starts pointing to the location u.
But, after the allocation of memory, b starts pointing to some other memory that was allocated by malloc say m.
Now you change the contents of memory m by use of b. But a is still pointing to the unknown location u.
So both the pointers are now pointing towards two different memory locations. So when you print contents where b is pointing it works perfectly and then you printf contents of a which has no specific location or may be null.
So, because of this your problem came.
And also, there is another error in your program that is in the printf of initialize function, it has given a parameter STRING which is undeclared....make it STRINGs.
Hope you will like the explanation. Its a little bit tricky.
Thanks :-)
You can use:
void Initialize(char** STRING)
Instead:
void Initialize(char* STRINGs)
because you want to change the the address to which STRING points
Also you have wrong prototype of main
Try:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void Initialize(char** STRING)
{
*STRING = malloc(6);
strcpy(*STRING, "hello");
printf("1: %s\n",*STRING);
}
int main (int argc, char *argv[])
{
char* STRING;
Initialize(&STRING);
printf("2: %s\n",STRING);
free(STRING);
return 0;
}
I am learning some new things and get stuck on a simple strcpy operation.
I don't understand why first time when I print works but second time it doesn't.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char *name;
char *altname;
name=(char *)malloc(60*sizeof(char));
name="Hello World!";
altname=name;
printf("%s \n", altname);
altname=NULL;
strcpy(altname,name);
printf("%s \n", altname);
return 1;
}
The problems start here:
name=(char *)malloc(60*sizeof(char));
name="Hello World!";
You replaced the value returned by malloc with a string literal.
You leaked memory (since you can't regain the pointer value returned by malloc). All calls to malloc are matched with a corresponding call to free. Since that pointer value is gone, the opportunity to call free with that pointer value is also gone.
You further on write to a NULL pointer, which is undefined behavior (which in your case, produced a segmentation fault).
You need to allocate memory for altname :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char *name;
char *altname;
name=(char *)malloc(60*sizeof(char));
name="Hello World!";
altname=name;
printf("%s \n", altname);
altname=NULL;
// allocate memory, so strcpy has space to write on ;)
altname=(char *)malloc(60*sizeof(char));
strcpy(altname,name);
printf("%s \n", altname);
return 1;
}
The first time, you are making altname point to the same place as name. This is OK, because name points to a valid char* (the first element ofthe "Hello World!" literal)
// both point to beginning of "Hello World!" literal
altname=name;
The second time, you attempt to copy the data pointed at by name into the place pointed at by altname, which at this stage points to NULL. So you attempt to write to NULL, which is the source of the error.
strncpy requires that the destination buffer be writable, and large enough to copy the source string's data into. You need to make altname point to a buffer that is large enough for the contents of the string name points to.
altname = (char*)malloc(60*strlen(name)+1); // +1 for nul terminator
strcpy(altname, name);
Also note that when you set name = "Hello World!", you leak the memory it originally pointed to. You need to free that first:
free(name);
name = "Hello World!";
You are trying to assign value to altname which has no space to store. First allocate memory to altname then assign
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char *name;
char *altname;
name=(char *)malloc(60*sizeof(char));
name="Hello World!";
altname=name;
printf("%s \n", altname);
altname=NULL;
altname=(char *)malloc(sizeof(name)); // allocate memory
strcpy(altname,name); // Now assign
printf("%s \n", altname);
return 1;
}
The two following codes are similar but the first has a structure, the second not.
Why this code works (with no warnings)?
#include <stdio.h>
#include <string.h>
struct prova
{
char *stringa;
};
int main()
{
struct prova p;
strcpy (p.stringa, "example\0");
printf("%s\n", p.stringa);
return 0;
}
But the following code doesn't work?
Segmentation fault (core dumped)
With this warning:
code.c: In function ‘main’:
code.c:8:9: warning: ‘stringa’ is used uninitialized in this function [-Wuninitialized]
strcpy (stringa, "example\0");
#include <stdio.h>
#include <string.h>
int main()
{
char *stringa;
strcpy (stringa, "example\0");
printf("%s\n", stringa);
return 0;
}
Thank you!
Neither is correct because you copy to an address specified by an uninitialized variable. Therefore both programs invoke undefined behaviour.
The fact that one of the programs works is down to pure chance. One possible form of undefined behaviour is that your program runs correctly.
You need to initialize the pointer to refer to a sufficiently sized block of memory. For instance:
char *stringa = malloc(8);
Note that you do not need to add a null terminator to a string literal. That is implicit. So, given this memory allocation you can then write:
strcpy(stringa, "example");
You need to give the string some memory for it copy the characters to.
Use malloc
besides the first example does not compile.
When you write
struct prova
{
char *stringa;
};
int main()
{
struct prova p;
strcpy (p.stringa, "example\0");
notice that p.stringa points to nowhere in particular but you copy to it.