char pointer not returning proper value - c

In below code ptr prints "hello world" but temp is blank though I am passing temp as address.What can be possible reasons?
#include <stdio.h>
#include <string.h>
#include <malloc.h
unsigned char temp[1024];
void func(unsigned char *ptr)
{
const char* x = "hello world";
ptr = (unsigned char*) x;
printf("ptr=%s\n",ptr);
}
int main ()
{
func(temp);
printf("temp=%s\n",temp);
return 0;
}

This is due to the shadow parameter passing used in C.
On the inside of func, you are changing a local shadow of temp and making it point to "hello world" interned string. This does not change the original pointer temp in main context.
In order to change temp you must pass a pointer to temp in and adjust it:
#include <stdio.h>
#include <stdlib.h>
void func(unsigned char **ptr)
{
const char *x = "hello world";
*ptr = (unsigned char*) x;
}
int main ()
{
unsigned char *temp;
func(&temp);
printf("temp=%s\n",temp);
return 0;
}

Related

Receiving a string as a void pointer parameter and using strcpy to change it

Here's the code:
#include <stdio.h>
#include <string.h>
void print (void*);
int main (void)
{
char *a = "Mcwhat";
print(&a);
printf("\n%s", a);
return 0;
}
void print (void *text)
{
char* pchar[5];
*pchar = (char*)text;
strcpy( *pchar, "Mcthat" );
}
I am trying to make Mcwhat into Mcthat using a void parameter, but the printf gives me a segmentation fault afterwards. Where is my mistake? I managed to do it char by char but now I want to change the whole string. Didn't found enough material on this in the books on C I have.
Keep it simple and pay attention to the type of your variables :
#include <stdio.h>
#include <string.h>
void print (void*);
int main()
{
char a[] = "Mcwhat"; // a is now a read-write array
print(a); // a decays to a pointer, don't take its adress or you'll get a pointer-to-pointer
printf("\n%s", a);
return 0;
}
void print (void *text)
{
strcpy( text, "Mcthat" ); // Don't dereference text here
}
Note that this "print" function is unsafe in all imaginable ways, but that wasn't the question.
There are lot of issues in your code:
1. Char array should be big enough to store the string. char[5] cannot hold Mswhat.
2. char* pchar [5] declares 5 char pointers, whereas you need one char pointer pointing to a char array.
I have corrected it.
#include <stdio.h>
#include <string.h>
void print (char*);
int main (void)
{
char *a = malloc(10);
strcpy(a,"Mcwhat");
print(a);
printf("\n%s", a);
free(a);
return 0;
}
void print (char *text)
{
char *pchar = text;
strcpy( pchar, "Mcthat" );
}
Just write it like that
void print (char *text)
{
strcpy( text, "Mcthat" );
}
But make sure, the that size of text is large enough to put "Mcthat" inside it.
Also in main:
print(a);
instead of
print(&a); // would requite void print (char** text)
tho whole shebang:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void print (void*);
int main (void)
{
char *a = malloc(strlen("Mcwhat")+1);
print(a);
printf("\n%s\n", a);
free(a);
return 0;
}
void print (void *text)
{
strcpy(text, "Mcthat" );
}

How can I fix a pointer error in C?

I am starting to learn about pointers in C.
How can I fix the error that I have in function x()?
This is the error:
Error: a value of type "char" cannot be assigned to an entity of type "char *".
This is the full source:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
void x(char **d, char s[]) {
d = s[0]; // here i have the problem
}
void main() {
char *p = NULL;
x(&p, "abc");
}
In function x() you pass d which is a char ** (a pointer to a string pointer), and char s[] (an array of char, passed as similarly to a pointer to char).
So in the line:
d = s[0];
s[0] is a char, whereas char **d is a pointer to a pointer to char. These are different, and the compiler is saying you cannot assign from one to the other.
However, did your compiler really warn you as follows?
Error: a value of type "char" cannot be assigned to an entity of type "char *"
Given the code sample, it should have said char ** at the end.
I think what you are trying to make x do is copy the address of the string passed as the second argument into the first pointer. That would be:
void x(char **d, char *s)
{
*d = s;
}
That makes p in the caller point to the constant xyz string but does not copy the contents.
If the idea was to copy the string's contents:
void x(char **d, char *s)
{
*d = strdup(s);
}
and ensure you remember to free() the return value in main(), as well as adding #include <string.h> at the top.
A more proper way would be to use strcpy:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
void x(char **d) {
*d = malloc(4 * sizeof(char));
strcpy(*d, "abc");
}
int main() {
char *p;
x(&p);
printf("%s", p);
free(p);
return 0;
}
Outputs: abc

How to make a copy of a string and return its address, assign that to a pointer and print the new string in C? [duplicate]

This question already has answers here:
Passing address of array as a function parameter
(6 answers)
Closed 9 years ago.
I'm writing a function that gets a string, allocates memory on the heap that's enough to create a copy, creates a copy and returns the address of the beginning of the new copy.
In main I would like to be able to print the new copy and afterwards use free() to free the memory. I think the actual function works although I am not the char pointer has to be static, or does it?
The code in main does not work fine...
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int make_copy(char arr[]);
int main()
{
char arrr[]={'a','b','c','d','e','f','\0'};
char *ptr;
ptr=make_copy(arrr);
printf("%s",ptr);
getchar();
return 0;
}
int make_copy(char arr[])
{
static char *str_ptr;
str_ptr=(char*)malloc(sizeof(arr));
int i=0;
for(;i<sizeof str_ptr/sizeof(char);i++)
str_ptr[i]=arr[i];
return (int)str_ptr;
}
OK, so based on the comments. A revised version:
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
char* make_copy(char arr[]);
int main()
{
char arrr[]={"abcdef\0"};
char *ptr=make_copy(arrr);
printf("%s",ptr);
getchar();
return 0;
}
char* make_copy(char arr[])
{
static char *str_ptr;
str_ptr=(char*)malloc(strlen(arr)+1);
int i=0;
for(;i<strlen(arr)+1;i++)
str_ptr[i]=arr[i];
return str_ptr;
}
Or even better:
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char* make_copy(char arr[]);
int main()
{
char arrr[]={"abcdef\0"};
printf("%s",make_copy(arrr));
getchar();
return 0;
}
char* make_copy(char arr[])
{
char *str_ptr;
str_ptr=(char*)malloc(strlen(arr)+1);
return strcpy(str_ptr,arr);
}
You're on the right track, but there are some issues with your code:
Don't use int when you mean char *. That's just wrong.
Don't list characters when defining a string, write char arrr[] = "abcdef";
Don't scale string alloations by sizeof (char); that's always 1 so it's pointless.
Don't re-implement strcpy() to copy a string.
Don't cast the return value of malloc() in C.
Don't make local variables static for no reason.
Don't use sizeof on an array passed to a function; it doesn't work. You must use strlen().
Don't omit including space for the string terminator, you must add 1 to the length of the string.
UPDATE Your third attempt is getting closer. :) Here's how I would write it:
char * make_copy(const char *s)
{
if(s != NULL)
{
const size_t size = strlen(s) + 1;
char *d = malloc(size);
if(d != NULL)
strcpy(d, s);
return d;
}
return NULL;
}
This gracefully handles a NULL argument, and checks that the memory allocation succeeded before using the memory.
First, don't use sizeof to determine the size of your string in make_copy, use strlen.
Second, why are you converting a pointer (char*) to an integer? A char* is already a pointer (a memory address), as you can see if you do printf("address: %x\n", ptr);.
sizeof(arr) will not give the exact size. pass the length of array to the function if you want to compute array size.
When pass the array to function it will decay to pointer, we cannot find the array size using pointer.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *strdup(const char *str)
{
char *s = (char*)malloc(strlen(str)+1);
if (s == NULL) return NULL;
return strcpy(s, str);
}
int main()
{
char *s = strdup("hello world");
puts(s);
free(s);
}
Points
~ return char* inside of int.
~ you can free the memory using below line
if(make_copy!=NULL)
free(make_copy)
Below is the modified code.
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
char* make_copy(char arr[]);
int main()
{
char arrr[]={'a','b','c','d','e','f','\0'};
char *ptr;
ptr=make_copy(arrr,sizeof(arrr)/sizeof(char));
printf("%s",ptr);
printf("%p\n %p",ptr,arrr);
getchar();
return 0;
}
char* make_copy(char arr[],int size)
{
char *str_ptr=NULL;
str_ptr=(char*)malloc(size+1);
int i=0;
for(;i<size;i++)
str_ptr[i]=arr[i];
str_ptr[i]=0;
return str_ptr;
}

Return a string from function to main

I want to return a string from a function (in the example funzione) to main. How to do this? Thank you!
#include <stdio.h>
#include <string.h>
#define SIZE (10)
/* TODO*/ funzione (void)
{
char stringFUNC[SIZE];
strcpy (stringFUNC, "Example");
return /* TODO*/;
}
int main()
{
char stringMAIN[SIZE];
/* TODO*/
return 0;
}
[EDITED] For those who need it, the complete version of the previous code (but without stringMAIN) is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE (10)
char *funzione (void)
{
char *stringa = malloc(SIZE);
strcpy (stringa, "Example");
return stringa;
}
int main()
{
char *ptr = funzione();
printf ("%s\n", ptr);
free (ptr);
return 0;
}
A string is a block of memory of variable length, and C cannot returns such objects (at least not without breaking compatibility with code that assumes strings cannot be returned)
You can return a pointer to a string, and in this case you have two options:
Option 1. Create the string dynamically within the function:
char *funzione (void)
{
char *res = malloc (strlen("Example")+1); /* or enough room to
keep your string */
strcpy (res, "Example");
return res;
}
In this case, the function that receives the resulting string is responsible for deallocate the memory used to build it. Failure to do so will lead to memory leaks in your program.
int main()
{
char *str;
str = funzione();
/* do stuff with str */
free (str);
return 0;
}
Option 2. Create a static string inside your function and returns it.
char *funzione (void)
{
static char str[MAXLENGTHNEEDED];
strcpy (str, "Example");
return str;
}
In this case you don't need to deallocate the string, but be aware that you won't be able to call this function from different threads in your program. This function is not thread-safe.
int main()
{
char *str;
str = funzione();
/* do stuff with str */
return 0;
}
Note that the object returned is a pointer to the string, so on both methods, the variable that receives the result from funzione() is not a char array, but a pointer to a char array.
#include <stdio.h>
#include <string.h>
#define SIZE 10
const char *funzione (void){
const char *string = "Example";
if(strlen(string) >= SIZE)
return "";
return string;
}
int main(void){
char stringMAIN[SIZE];
strcpy(stringMAIN, funzione());
printf("%s", stringMAIN);
return 0;
}
You can do this as
char *funzione (void)
{
char *stringFUNC = malloc(SIZE);
strcpy (stringFUNC, "Example");
return stringFUNC;
}
In main, call it as
int main()
{
char stringMAIN[SIZE];
char *ptr = funzione ()
...
free(ptr);
return 0;
}

Allocate space for struct pointer in subfunction

How can I allocate memory for a struct pointer and assign value to it's member in a subfunction?
The following code will compile but not execute:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct _struct {char *str;};
void allocate_and_initialize(struct _struct *s)
{
s = calloc(sizeof(struct _struct), 1);
s->str = calloc(sizeof(char), 12);
strcpy(s->str, "hello world");
}
int main(void)
{
struct _struct *s;
allocate_and_initialize(s);
printf("%s\n", s->str);
return 0;
}
You are passing s by value. The value of s is unchanged in main after the call to allocate_and_initialize
To fix this you must somehow ensure that the s in main points to the memory chunk allocated by the function. This can be done by passing the address of s to the function:
// s is now pointer to a pointer to struct.
void allocate_and_initialize(struct _struct **s)
{
*s = calloc(sizeof(struct _struct), 1);
(*s)->str = calloc(sizeof(char), 12);
strcpy((*s)->str, "hello world");
}
int main(void)
{
struct _struct *s = NULL; // good practice to make it null ptr.
allocate_and_initialize(&s); // pass address of s.
printf("%s\n", s->str);
return 0;
}
Alternatively you can return the address of the chunk allocated in the function back and assign it to s in main as suggested in other answer.
In your example:
void allocate_and_initialize(struct _struct *s)
{
s = calloc(sizeof(struct _struct), 1);
s->str = calloc(sizeof(char), 12);
strcpy(s->str, "hello world");
}
Assigning to s here doesn't change s in the caller. Why not return it instead?
struct _struct *allocate_and_initialize(void) {
struct _struct *s;
s = calloc(sizeof *s, 1);
s->str = calloc(1, 12); /* sizeof(char) is always 1 */
strcpy(s->str, "hello world");
return s;
}
and use it thus:
struct _struct *s;
s = allocate_and_initialize();
/* use s... */
free(s); /* don't forget to free the memory when you're done */
you must change your code like that:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct _struct {char *str;};
void allocate_and_initialize(struct _struct **s)
{
*s = (_struct*)calloc(sizeof(struct _struct), 1);
(*s)->str = (char*)calloc(sizeof(char), 12);
strcpy((*s)->str, "hello world");
}
int main(void)
{
struct _struct *s;
allocate_and_initialize(&s);
printf("%s\n", s->str);
return 0;
}
The reason is, that you change the adress of the pointer, but not the "content" of the pointer. So, if you code in c, you have to use a "double" pointer. If you code in c++ you can use a reference.
You can create struct object then pass its address to subfunction, then assign values in subfunction by creating pointer. The exact code is,
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct _struct {char *str;};
void allocate_and_initialize(struct _struct *s)
{
s -> str = malloc(12);
strcpy(s->str, "hello world");
}
void main(void)
{
struct _struct _struct;
allocate_and_initialize(&_struct);
printf("%s\n", _struct.str);
}

Resources