Basically at the most basic level I cant understand why can't I do this:
#include <stdio.h>
#include <stdlib.h>
void mal(char *str){
str = malloc(sizeof(char));
}
int main(void)
{
char *s;
mal(s);
free(s);
return 0;
}
s gets passed by value to the function mal. Inside mal the local parameter str gets changed by the assignment, but s in main is kept uninitialized. In C you should pass a pointer to s to mal to resolve this problem:
#include <stdio.h>
#include <stdlib.h>
void mal(char **str){ // pointer to pointer
*str = malloc(sizeof(char)); // referenced variable behind str changed
}
int main(void)
{
char *s;
mal(&s); // pointer to s passed
free(s);
return 0;
}
Related
this is the code. the function "leggi" is supposed to read the value of c[i].a but when I type the first number in the console the program crashes.
It's probably a pointers issue but i can't figure it out
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef struct cane{
int a;
}cane;
void leggi(cane *c[20]){
int i;
for(i=0;i<5;i++)
scanf("%d", &c[i]->a );
}
int main(){
int i;
cane c[20];
leggi(&c);
for(i=0;i<5;i++)
printf("%d",c[i].a);
return 0;
}
You pass the wrong type to the function.
If you want to pass an array to a function the array name decays to a pointer to its first element, therefore the argument is only a pointer to the type:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef struct cane{
int a;
}cane;
void leggi(cane *c){
int i;
for(i=0;i<5;i++)
scanf("%d", &(c[i].a) );
}
int main(){
int i;
cane c[20];
leggi(c);
for(i=0;i<5;i++)
printf("%d",c[i].a);
return 0;
}
The type of &c is cane (*)[20] i.e. a pointer to an array. You've declared the argument of the function to be cane *[20] which is (as a function argument) a cane** which is a pointer to a pointer.
You may have intended to pass a pointer to an element of the array instead:
void leggi(cane *c)
// ...
scanf("%d", &c[i].a );
//
leggi(c);
Or possibly you really intended to pass a pointer to the array instead:
void leggi(cane (*c)[20])
scanf("%d", &(*c)[i].a )
//
leggi(&c);
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" );
}
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
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;
}
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;
}