I tried 2 different approaches to build a function that accepts string input from user and stores it in a variable.
char* input(size_t size)
{
char buffer[size];
char* str = (char*)malloc(sizeof(char) * sizeof(buffer));
if (fgets(buffer, size, stdin) != NULL)
{
buffer[strcspn(buffer, "\n")] = '\0';
printf("Buffer says: %s\n", buffer);
strncpy(str, buffer, sizeof(buffer));
str[sizeof(buffer) - 1] = '\0';
printf("str inside function says: %s\n", str);
return str;
}
return NULL;
}
int input2(char* str, size_t size)
{
char buffer[size];
str = (char*)malloc(sizeof(char) * sizeof(buffer));
if (fgets(buffer, size, stdin) != NULL)
{
buffer[strcspn(buffer, "\n")] = '\0';
printf("Buffer says: %s\n", buffer);
strncpy(str, buffer, sizeof(buffer));
str[sizeof(buffer) - 1] = '\0';
printf("str inside function says: %s\n", str);
return 0;
}
return -1;
}
main.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libs/custom/myio.h"
int main(int argc, char const *argv[])
{
char *ip1;
ip1 = input(1000);
printf("ip1 inside main says %s\n", ip1);
free(ip1);
char* ip2;
input2(ip2, 1000);
printf("ip2 inside main says %s\n", ip2);
free(p2);
return 0;
}
When running the program:
Hi # user input
Buffer says: Hi
str inside function says: Hi
ip1 inside main says Hi
Hi # user input
Buffer says: Hi
str inside function says: Hi
ip2 inside main says (null)
A works perfectly but B doesn't. A is not the approach that I want to use, I prefer to use B instead.
When I tried debugging with valgrind along with gdb, it seems that it is detecting errors in the printf
function (??).
==177193== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
==177193==
==177193== 1 errors in context 1 of 2:
==177193== Conditional jump or move depends on uninitialised value(s)
==177193== at 0x48D71C2: __vfprintf_internal (vfprintf-internal.c:1688)
==177193== by 0x48C1EBE: printf (printf.c:33)
==177193== by 0x109276: main (main.c:19)
==177193== Uninitialised value was created by a stack allocation
==177193== at 0x109209: main (main.c:7)
==177193==
==177193== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
I have done a lot of research but I am still getting no where on why B is not working.
The problem in the function input2
("Implementation B") is that the line
str = (char*)malloc(sizeof(char) * sizeof(buffer));
will only modify the pointer variable str
in the function input2
, which contains a copy of the value of the variable ip2
in the function main
. It will not set the value of the original variable ip2
in the function main
.
If you want the variable ip2
to be affected by this line of code, then, instead of passing the value of the variable ip2
to the function input2
, you should instead pass a pointer to this variable, by changing the parameters of the function to the following:
int input2( char** str, size_t size )
and by changing the line
str = (char*)malloc(sizeof(char) * sizeof(buffer));
to:
*str = (char*)malloc(sizeof(char) * sizeof(buffer));
Now, when calling the function input2
in main
, instead of passing the value of ip2
, you should instead pass the address of that variable, like this:
input2( &ip2, 1000 );
Now, this variable should also be affected by the changes in the function input2
.
Also, it is worth noting that in C (in contrast to C++), it is not necessary to cast the result of malloc
. See this question for further information: Do I cast the result of malloc?