Unable to pass char pointer to gethostname (Linux) - c

The following C program attempts to fetch and print the host name of the current RHEL host. It throws a segmentation fault on this machine. As per the definition of gethostname I should be able to pass a char pointer, shouldn't I?
When I use a char array instead (like char hname[255]), the call to gethostname works. (If I did this how would I return the array to main?)
#include <stdio.h>
#include <unistd.h>
char * fetchHostname()
{
// using "char hname[255]" gets me around the issue;
// however, I dont understand why I'm unable to use
// a char pointer.
char *hname;
gethostname(hname, 255 );
return hname;
}
int main()
{
char *hostname = fetchHostname();
return 0;
}
Output:
pmn#rhel /tmp/temp > gcc -g test.c -o test
pmn#rhel /tmp/temp >
pmn#rhel /tmp/temp > ./test
Segmentation fault
pmn#rhel /tmp/temp >

As gethostname man said:
The gethostname() function shall return the standard host name for
the current machine. The namelen argument shall
specify the size of the array pointed to by the name argument.
The returned name shall be null-terminated, except that
if namelen is an insufficient length to hold the host name,
then the returned name shall be truncated and it is
unspecified whether the returned name is null-terminated.
You need a place to store the function information, so declare hostname as an array, not a pointer.
#include <unistd.h>
char * fetchHostname(char *hostname, int size)
{
// using "char hname[255]" gets me around the issue;
// however, I dont understand why I'm unable to use
// a char pointer.
gethostname(hostname, size);
return hostname;
}
int main()
{
char hostname[HOST_NAME_MAX + 1];
fetchHostname(hostname, HOST_NAME_MAX);
return 0;
}

When I use a char array instead (like char hname[255]), the call to
gethostname works. (If I did this how would I return the array to
main?)
By passing a pointer to the array from main() to your function. Note that this approach makes your function fetchHostname() to be just a wrapper for function gethostname():
#include <stdio.h>
#include <unistd.h>
void fetchHostname(char *hname)
{
gethostname(hname,255);
}
int main()
{
char hostname[256];
fetchHostname(hostname);
return 0;
}
Or by declaring your hname[] array local static, so it is valid even after the program leaves the function (this approach is not thread-safe):
#include <stdio.h>
#include <unistd.h>
char *fetchHostname (void)
{
static char hname[256];
gethostname(hname,255);
return hname;
}
int main()
{
char *hostname;
hostname = fetchHostname();
return 0;
}

Though there are many technically correct answers I don't think that they actually explain to you where you went wrong.
gethostname(char *name, size_t len); is documented here and it basically says that the parameter name is an array of characters that you have allocated where this function will copy the hostname into. And how you do that is explained in the many other wonderful answers here.
That is why this works if you make the array yourself but causes a segmentation fault if you just give it a pointer.
Also, you were giving this function an uninitialized pointer so when it tried to copy data to that address (which is just some completely random place in memory) it caused your program to terminate because it was trying to write a string where it isn't allowed to.
This type of mistake tells me that you need to brush up on what pointers actually are and that you need to understand that they can be used to allow a function to return a value in a different way than using the return statement.

Update: please see #Tio Pepe's answer.
You need to allocate space in your array (either statically or dynamically):
char hname[HOST_NAME_MAX + 1];
otherwise you are passing an uninitialised pointer that could point anywhere.
Your call to gethostname():
gethostname(hname, 255);
is a contract that says here is a pointer that points to at least 255 characters of allocated space.
Also, you are trying to return a pointer to space allocated on the stack. That's not good.
Yoi need to dynamically allocate the character array if you want to return it.
char * hname;
hname = malloc((HOST_NAME_MAX +1) * sizeof(char));
But be aware that you now have to manage when that space gets freed.

Returning a pointer to a local variable is undefined behavior, because it will go out of scope. If you allocate it on the heap (via dynamic allocation), you will not have this problem.
char * fetchHostname()
{
char* hname= malloc(sizeof(char) * 256);
gethostname(hname, 255);
return hname;
}
int main()
{
char *hostname = fetchHostname();
printf(hostname);
free(hostname);
return 0;
}

char *hname; //defined inside a function and would be destroyed after the function is executed
After the execution of fetchHostname() the address returned to the hostname is not valid and acessing it would result in segmentation fault

Related

return a string after being concantenated using strcpy and strcat [duplicate]

I haven't used C in over 3 years, I'm pretty rusty on a lot of things.
I know this may seem stupid but I cannot return a string from a function at the moment. Please assume that: I cannot use string.h for this.
Here is my code:
#include <ncurses.h>
char * getStr(int length)
{
char word[length];
for (int i = 0; i < length; i++)
{
word[i] = getch();
}
word[i] = '\0';
return word;
}
int main()
{
char wordd[10];
initscr();
*wordd = getStr(10);
printw("The string is:\n");
printw("%s\n",*wordd);
getch();
endwin();
return 0;
}
I can capture the string (with my getStr function) but I cannot get it to display correctly (I get garbage).
Help is appreciated.
Either allocate the string on the stack on the caller side and pass it to your function:
void getStr(char *wordd, int length) {
...
}
int main(void) {
char wordd[10 + 1];
getStr(wordd, sizeof(wordd) - 1);
...
}
Or make the string static in getStr:
char *getStr(void) {
static char wordd[10 + 1];
...
return wordd;
}
Or allocate the string on the heap:
char *getStr(int length) {
char *wordd = malloc(length + 1);
...
return wordd;
}
char word[length];
char *rtnPtr = word;
...
return rtnPtr;
This is not good. You are returning a pointer to an automatic (scoped) variable, which will be destroyed when the function returns. The pointer will be left pointing at a destroyed variable, which will almost certainly produce "strange" results (undefined behaviour).
You should be allocating the string with malloc (e.g. char *rtnPtr = malloc(length)), then freeing it later in main.
You are allocating your string on the stack, and then returning a pointer to it. When your function returns, any stack allocations become invalid; the pointer now points to a region on the stack that is likely to be overwritten the next time a function is called.
In order to do what you're trying to do, you need to do one of the following:
Allocate memory on the heap using malloc or similar, then return that pointer. The caller will then need to call free when it is done with the memory.
Allocate the string on the stack in the calling function (the one that will be using the string), and pass a pointer in to the function to put the string into. During the entire call to the calling function, data on its stack is valid; its only once you return that stack allocated space becomes used by something else.
Your pointer is pointing to local variable of the function. So as soon as you return from the function, memory gets deallocated. You have to assign memory on heap in order to use it in other functions.
Instead
char *rtnPtr = word;
do this
char *rtnPtr = malloc(length);
So that it is available in the main function. After it is used free the memory.
As others already said, you can't return a non-constant string in a useful way without allocating it on the heap (e.g. using strdup). But in all recent versions of the C standard (C89 and later if I'm not mistaken) you can return a struct. It won't be necessary for the caller to deallocate the result because it's not on the heap. And it's thread-safe.
#include <stdio.h>
struct stringbuf
{
char buf[40];
};
struct stringbuf getanswer(int i)
{
struct stringbuf result = { 0 };
snprintf(result.buf, sizeof(result.buf), "The answer is %d", i);
return result;
}
int main(int argc, char **argv)
{
/*
* Remember to pass the .buf member, not the struct, to functions
* such as printf which expect a character pointer as argument!
* Passing the result of getanswer in the next line without .buf
* appended, will likely crash the program because the program
* will put the entire struct on the stack, not a character
* pointer, and will make printf interpret the first few bytes
* of the string as a pointer. That would be bad.
*/
printf("How many arguments did I get? %s\n", getanswer(argc).buf);
return 0;
}
Note: To keep the sample code as simple and focused as possible, I simply declared a struct type without typedef. You may save yourself a lot of typing by using typedef and returning the defined type.
There are (arguably) a few disadvantages:
A function that returns a struct cannot return NULL.
The size of the buffer in the struct is fixed because the compiler has to know the size of the return type at compile time.
The result of a function that returns a struct is probably stored on the stack; this may be a problem in small systems (like microcontrollers) that don't have a lot of stack space.
Unlike character arrays, an instance of a struct is not a usable alias for the string that's stored in it. In other words, whereas you can create an array of characters and use its name as a pointer to the first character, you can't use the name of a struct as a pointer.
That last point is important because you have to keep in mind that a struct with a character array is not the same as the array itself. So if you want to call a string function, you should pass the string member variable, not a pointer to the struct. This is especially important for functions with variadic arguments such as printf and friends where a compiler may not warn you if you're doing it wrong: passing a struct will place the entire struct on the stack, not just a pointer to the first character. Printf will interpret the first few characters in the struct as a character pointer, which will certainly be invalid.
Yes, it's possible to cast a pointer to a struct to a char * and pass it to a string function (including printf) and that will work correctly, but I would argue that it's bad practice to do this: If you (or someone else) ever decides to put another member variable in the struct declaration in front of the string buffer, any use of a typecast pointer to a struct that assumes that the string buffer starts where the struct starts, would silently fail. You probably want to avoid this, so use a pointer to the string member variable even if it's somewhat inconvenient.
===Jac
word is on the stack and goes out of scope as soon as getStr() returns. You are invoking undefined behavior.
I came across this thread while working on my understanding of Cython. My extension to the original question might be of use to others working at the C / Cython interface. So this is the extension of the original question: how do I return a string from a C function, making it available to Cython & thus to Python?
For those not familiar with it, Cython allows you to statically type Python code that you need to speed up. So the process is, enjoy writing Python :), find its a bit slow somewhere, profile it, calve off a function or two and cythonize them. Wow. Close to C speed (it compiles to C) Fixed. Yay. The other use is importing C functions or libraries into Python as done here.
This will print a string and return the same or another string to Python. There are 3 files, the c file c_hello.c, the cython file sayhello.pyx, and the cython setup file sayhello.pyx. When they are compiled using python setup.py build_ext --inplace they generate a shared library file that can be imported into python or ipython and the function sayhello.hello run.
c_hello.c
#include <stdio.h>
char *c_hello() {
char *mystr = "Hello World!\n";
return mystr;
// return "this string"; // alterative
}
sayhello.pyx
cdef extern from "c_hello.c":
cdef char* c_hello()
def hello():
return c_hello()
setup.py
from setuptools import setup
from setuptools.extension import Extension
from Cython.Distutils import build_ext
from Cython.Build import cythonize
ext_modules = cythonize([Extension("sayhello", ["sayhello.pyx"])])
setup(
name = 'Hello world app',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
)
Easier still: return a pointer to a string that's been malloc'd with strdup.
#include <ncurses.h>
char * getStr(int length)
{
char word[length];
for (int i = 0; i < length; i++)
{
word[i] = getch();
}
word[i] = '\0';
return strdup(&word[0]);
}
int main()
{
char wordd[10];
initscr();
*wordd = getStr(10);
printw("The string is:\n");
printw("%s\n",*wordd);
getch();
endwin();
return 0;
}

Passing string from function to another string C [duplicate]

I haven't used C in over 3 years, I'm pretty rusty on a lot of things.
I know this may seem stupid but I cannot return a string from a function at the moment. Please assume that: I cannot use string.h for this.
Here is my code:
#include <ncurses.h>
char * getStr(int length)
{
char word[length];
for (int i = 0; i < length; i++)
{
word[i] = getch();
}
word[i] = '\0';
return word;
}
int main()
{
char wordd[10];
initscr();
*wordd = getStr(10);
printw("The string is:\n");
printw("%s\n",*wordd);
getch();
endwin();
return 0;
}
I can capture the string (with my getStr function) but I cannot get it to display correctly (I get garbage).
Help is appreciated.
Either allocate the string on the stack on the caller side and pass it to your function:
void getStr(char *wordd, int length) {
...
}
int main(void) {
char wordd[10 + 1];
getStr(wordd, sizeof(wordd) - 1);
...
}
Or make the string static in getStr:
char *getStr(void) {
static char wordd[10 + 1];
...
return wordd;
}
Or allocate the string on the heap:
char *getStr(int length) {
char *wordd = malloc(length + 1);
...
return wordd;
}
char word[length];
char *rtnPtr = word;
...
return rtnPtr;
This is not good. You are returning a pointer to an automatic (scoped) variable, which will be destroyed when the function returns. The pointer will be left pointing at a destroyed variable, which will almost certainly produce "strange" results (undefined behaviour).
You should be allocating the string with malloc (e.g. char *rtnPtr = malloc(length)), then freeing it later in main.
You are allocating your string on the stack, and then returning a pointer to it. When your function returns, any stack allocations become invalid; the pointer now points to a region on the stack that is likely to be overwritten the next time a function is called.
In order to do what you're trying to do, you need to do one of the following:
Allocate memory on the heap using malloc or similar, then return that pointer. The caller will then need to call free when it is done with the memory.
Allocate the string on the stack in the calling function (the one that will be using the string), and pass a pointer in to the function to put the string into. During the entire call to the calling function, data on its stack is valid; its only once you return that stack allocated space becomes used by something else.
Your pointer is pointing to local variable of the function. So as soon as you return from the function, memory gets deallocated. You have to assign memory on heap in order to use it in other functions.
Instead
char *rtnPtr = word;
do this
char *rtnPtr = malloc(length);
So that it is available in the main function. After it is used free the memory.
As others already said, you can't return a non-constant string in a useful way without allocating it on the heap (e.g. using strdup). But in all recent versions of the C standard (C89 and later if I'm not mistaken) you can return a struct. It won't be necessary for the caller to deallocate the result because it's not on the heap. And it's thread-safe.
#include <stdio.h>
struct stringbuf
{
char buf[40];
};
struct stringbuf getanswer(int i)
{
struct stringbuf result = { 0 };
snprintf(result.buf, sizeof(result.buf), "The answer is %d", i);
return result;
}
int main(int argc, char **argv)
{
/*
* Remember to pass the .buf member, not the struct, to functions
* such as printf which expect a character pointer as argument!
* Passing the result of getanswer in the next line without .buf
* appended, will likely crash the program because the program
* will put the entire struct on the stack, not a character
* pointer, and will make printf interpret the first few bytes
* of the string as a pointer. That would be bad.
*/
printf("How many arguments did I get? %s\n", getanswer(argc).buf);
return 0;
}
Note: To keep the sample code as simple and focused as possible, I simply declared a struct type without typedef. You may save yourself a lot of typing by using typedef and returning the defined type.
There are (arguably) a few disadvantages:
A function that returns a struct cannot return NULL.
The size of the buffer in the struct is fixed because the compiler has to know the size of the return type at compile time.
The result of a function that returns a struct is probably stored on the stack; this may be a problem in small systems (like microcontrollers) that don't have a lot of stack space.
Unlike character arrays, an instance of a struct is not a usable alias for the string that's stored in it. In other words, whereas you can create an array of characters and use its name as a pointer to the first character, you can't use the name of a struct as a pointer.
That last point is important because you have to keep in mind that a struct with a character array is not the same as the array itself. So if you want to call a string function, you should pass the string member variable, not a pointer to the struct. This is especially important for functions with variadic arguments such as printf and friends where a compiler may not warn you if you're doing it wrong: passing a struct will place the entire struct on the stack, not just a pointer to the first character. Printf will interpret the first few characters in the struct as a character pointer, which will certainly be invalid.
Yes, it's possible to cast a pointer to a struct to a char * and pass it to a string function (including printf) and that will work correctly, but I would argue that it's bad practice to do this: If you (or someone else) ever decides to put another member variable in the struct declaration in front of the string buffer, any use of a typecast pointer to a struct that assumes that the string buffer starts where the struct starts, would silently fail. You probably want to avoid this, so use a pointer to the string member variable even if it's somewhat inconvenient.
===Jac
word is on the stack and goes out of scope as soon as getStr() returns. You are invoking undefined behavior.
I came across this thread while working on my understanding of Cython. My extension to the original question might be of use to others working at the C / Cython interface. So this is the extension of the original question: how do I return a string from a C function, making it available to Cython & thus to Python?
For those not familiar with it, Cython allows you to statically type Python code that you need to speed up. So the process is, enjoy writing Python :), find its a bit slow somewhere, profile it, calve off a function or two and cythonize them. Wow. Close to C speed (it compiles to C) Fixed. Yay. The other use is importing C functions or libraries into Python as done here.
This will print a string and return the same or another string to Python. There are 3 files, the c file c_hello.c, the cython file sayhello.pyx, and the cython setup file sayhello.pyx. When they are compiled using python setup.py build_ext --inplace they generate a shared library file that can be imported into python or ipython and the function sayhello.hello run.
c_hello.c
#include <stdio.h>
char *c_hello() {
char *mystr = "Hello World!\n";
return mystr;
// return "this string"; // alterative
}
sayhello.pyx
cdef extern from "c_hello.c":
cdef char* c_hello()
def hello():
return c_hello()
setup.py
from setuptools import setup
from setuptools.extension import Extension
from Cython.Distutils import build_ext
from Cython.Build import cythonize
ext_modules = cythonize([Extension("sayhello", ["sayhello.pyx"])])
setup(
name = 'Hello world app',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
)
Easier still: return a pointer to a string that's been malloc'd with strdup.
#include <ncurses.h>
char * getStr(int length)
{
char word[length];
for (int i = 0; i < length; i++)
{
word[i] = getch();
}
word[i] = '\0';
return strdup(&word[0]);
}
int main()
{
char wordd[10];
initscr();
*wordd = getStr(10);
printw("The string is:\n");
printw("%s\n",*wordd);
getch();
endwin();
return 0;
}

Segmentation fault passing an address specifically defined as a string

Here's more code I whipped up since i was having trouble with my major program that I now fixed.
I have a function which modifies a series of bytes. In this example, the function is supposed to fill up the first 9 bytes of the char array with the numbers 1 through 9 consecutively.
Two tests are run. The first one is calling the function where the parameter is (char*)&myvar. The second test only uses myvar as a parameter. I thought I always had to use an & in front of a char array pointer when I want the string returned in the parameter portion of the function.
Why does this program only work when I don't prepend (char*)& to my char array variable?
When I do apply it, I receive a segmentation fault.
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
int func(char* abc){
char *p=abc;
int n;
for (n=1;n<10;n++){
*p=(unsigned char)(n+48);p++;
}
return 0;
}
int main(){
char vars[1000]="234";
char *myvar=vars;
printf("Function test\n");
int result=func((char*)&myvar); //causes segfault
printf("Function result %s\n",myvar); //segfault here
printf("Function test again\n");
int result2=func(myvar); //works
printf("Function result %s\n",myvar);
printf("DONE\n");
return 0;
}
Why does this program only work when I don't prepend (char*)& to my char array variable?
Because doing that is completely wrong and not a thing that makes sense.
I thought I always had to use an & in front of a char array pointer when I want the string returned in the parameter portion of the function.
You don't. (Also, you do not have a "char array pointer", and "when I want the string returned in the parameter portion of the function" doesn't make sense.)
When you need to pass a char * to a function that takes a char *, you do not need to put any special prefix in front of the pointer. You just pass it directly, the way you did with
int result2=func(myvar);
You could also have passed in vars, due to the automatic conversion from an array to a pointer to its first element, just like you were able to do char *myvar=vars; without any special casting.

return multiple values from a function in C [duplicate]

This question already has an answer here:
Pointer losing its value + execv compilation warning
(1 answer)
Closed 7 years ago.
my original problem is that I want to write a function that can return me two values. I know that I can do it by passing the address of the two arguments to the function, and directly calculate their values inside that function. But when doing experiment, something weird happens. The value I got inside the function cannot survive to the main function:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void build(char *ch){
ch = malloc(30*sizeof(char));
strcpy(ch, "I am a good guy");
}
void main(){
char *cm;
build(cm);
printf("%s\n", cm);
}
The above program just prints out some garbage. So I want to know what's wrong here. Eventually, I want something like this parse(char **argv, char **cmd1, char **cmd2), which can parse out two commands for me from the original command argv. That would be great if anybody can explain a little bit. Thanks a lot.
build() take the pointer ch by value, i.e. a copy of the pointer is passed to the function. So any modifications you make to that value are lost when the function exits. Since you want your modification to the pointer to be visible in the caller's context, you need to pass a pointer to pointer.
void build(char **ch){
*ch = malloc(30*sizeof(char));
strcpy(*ch, "I am a good guy");
}
Also, you don't need to pass pointers to a function because you need to return multiple values. Another option is to create a struct that contains the values you wish to return as members, and then return an instance of said struct. I'd recommend this approach over the first if the values are related and it makes sense to package them together.
Here's a re-listing of your code after fixing bugs:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void build(char **ch){
*ch = malloc(30 * sizeof(char));
strcpy(*ch, "I am a good guy");
}
int main() { // main must return int
char *cm;
build(&cm); // pass pointer to pointer
printf("%s\n", cm);
free(cm); // free allocated memory
return 0; // main's return value, not required C99 onward
}
If you want to malloc inside the function, you need to pass the address to the outside pointer since ch inside the function is only a local variable, and changing it doesn't affect the outside cm variable
void build(char **ch){
*ch = malloc(30*sizeof(char));
strcpy(*ch, "I am a good guy");
}
void main(){
char *cm;
build(&cm);
printf("%s\n", cm);
}
But better don't malloc inside the function, instead just write what you want to the area pointed to by the pointer. This is the common way when you need to provide a buffer to get data in C. In this way users will have the choice to allocate memory their own, or just use a local buffer and don't need to free memory after that like you've just forgotten in your example
void build(char *ch){
strcpy(ch, "I am a good guy");
}
void main(){
char *cm1;
cm1 = malloc(30*sizeof(char));
build(cm1);
printf("%s\n", cm1);
char cm2[30];
build(cm2);
printf("%s\n", cm2);
free(cm1); // don't forget this
}
This is because in C, you cannot reassign the memory address of the pointer because it is passed by value.
If you really want to do this, you must pass the address of the pointer into the build function.
See: Passing pointer argument by reference under C?

*char into main and *char into a struct

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.

Resources