Confusion on memory management: global char * in C program - c

I have a program where I have a global char * that I'm going to constantly be changing. Right now, I set it to a value when it's NULL, and alter it when it's not. However, it's never not NULL, even if I'm setting the pointer. An example of what I'm saying:
char *a;
void function()
{
if(a == NULL)
{
a = "Test1";
}
else
{
a = "Test2";
}
}
Every time I go through this function, though, a is always null. I assume there's something I need to be doing with memory allocation, but I'm confused about where I would allocate it, and where I would free it. Thanks!

The first time function() gets called, 'a' will be NULL because global variables in C are initialized to zero.
You then set it to point to "Test1". The second time function() gets called, 'a' will still be a pointer to "Test1", not NULL, so you'll set it to "Test2". Every future call will essentially do nothing, setting 'a' to "Test2" again and again.
If that's not what you're seeing, then there is something different with your actual code compared to the code you posted above. For example, if "char *a" is inside of a function then it is a local variable, not a global, and it will be of undefined value on function entry and also lose its value every time the function exits.
The code below produced the output underneath it, as it should.
#include <stdlib.h>
#include <stdio.h>
char *a;
void function();
int main( int argc, const char *argv[] )
{
function();
function();
function();
function();
return 0;
}
void function()
{
printf( "function: a=%s", (a ? a : "NULL") );
if(a == NULL)
{
a = "Test1";
}
else
{
a = "Test2";
}
printf( " exiting a=%s\n", (a ? a : "NULL") );
}
This produces the following output:
function: a=NULL exiting a=Test1
function: a=Test1 exiting a=Test2
function: a=Test2 exiting a=Test2
function: a=Test2 exiting a=Test2

I feel a little sheepish for this. The problem was that I was forking the process, and editing the copy of the variable in the child process, without realizing that the parent process' variable was unaffected.
Sorry about that. Hope this helps someone else who runs into this.

I'm writing this as a "response" instead of a question so I can format the text better:
Q1) Does the behavior change if you initialize like this?
char *a = NULL;
Q2) what's your compiler, compiler version and OS?
Q3) are you sure there's no other code that might be messing with "a"?
==================================================
ADDENDUM:
Q: I just realized that I'm editing the variable's value in a child process after forking. Could that be the problem? – Mason
A: Only if you expect changing the variable in one process to somehow change the other process (without assigning a shared memory segment) ;)

Related

Check if a pointer to function is initialized

How can I check if a pointer to function was initialized?
I can check for NULL, but if not null could be garbage, right?
I have the following:
#include <stdio.h>
#include <stdlib.h>
typedef struct client_struct
{
char *name;
char *email;
void (*print)(struct client_struct *c);
} client;
void print_client(client *c)
{
if (c->print != NULL)
c->print(c);
}
int main()
{
client *c = (client *)malloc(sizeof(client));
c->email = (char *)malloc(50 * sizeof(char));
sprintf(c->email, "email#server.com");
c->name = (char *)malloc(50 * sizeof(char));
sprintf(c->name, "some name");
//Uncommenting line below work as expected, otherwise segmentation fault
//c->print = NULL;
print_client(c);
printf("\nEOF\n");
int xXx = getchar();
return 0;
}
How can I check if this pointer really points to function "void (*f)(client *)"?
Comparing size doesn't work because could garbage in same size, correct?
I would like a way to accomplish that preferably according to C standard.
As described in the comments, it is impossible to determine with 100% certainty whether a pointer is garbage.
To avoid such situation, you can provide a "constructor" function, like this:
struct client_struct* client_allocate()
{
struct client_struct* object = malloc(sizeof *object);
if (object)
{
object->name = NULL;
object->email = NULL;
object->print = NULL;
}
return object;
}
Then write in your documentation that the only valid way to create "clients" is by using your function. If you do this, you should also provide a destroy function, where you call free.
Suppose you add a new pointer to your struct one day. Then you update your client_allocate function, where you set this pointer to NULL, and the new pointer will always be properly initialized. There is no need to update all places in code where your struct is allocated, because now there is only one such place.
Caveats
Checking if a pointer to a function is initialized with an valid function is not an easily solvable problem. Any solution, will not be portable across platforms, and is also dependent on the binary format (statically or dynamically linkable formats) that you end up with. There are ways to do this, with varying success, on different binary formats, however I am not going to go over every permutation. Hopefully this will get you going down that rabbit hole :-) and you can figure out the particular solution that works for you in your circumstances.
In order for some of the solutions to work you have to ensure that the linked binaries have exported symbols (it's possible to do it without, but it's a lot harder and I don't have the time). So when you're linking your program ensure that you have dynamic symbols enabled.
Having said that, here's an approach you can use on systems using dlfcn functions. (See History below)
More Caveats
As #Deduplicator points out in his comment below, there may be situations where 0xdeadbeef may arbitrarily happen to point to a valid function, in which case you may end up with a situation where you end up calling the wrong valid function. There are ways to mitigate that situation at either compile-time or runtime but you'll have to build the solution by hand. For example, C++ does it by mangling in namespace into the symbols. You could require that to happen. (I'll think of an interesting way to do this and post it)
Linux / SysV variants (Mac OSX included)
Use dladdr (SysV) (GNU has a dladdr1 as well) to determine which function does the address you provide fall within:
Example:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dlfcn.h>
int is_valid_function_ptr( void *func) {
Dl_info info;
int rc;
rc = dladdr(func, &info);
if (!rc) {
/* really should do more checking here */
return 0;
}
return 1; /* you can print out function names and stuff here */
}
void print(const char *value) {
fprintf(stdout, "%s", value);
}
void call_the_printer(void (*foo)(), const char *value)
{
if(is_valid_function_ptr(foo)) {
foo(value);
}
else {
fprintf(stderr, "The Beef is Dead!\n");
}
}
int main()
{
void (*funcptr)() = (void (*)()) 0xdeadbeef; /* some dead pointer */
call_the_printer(funcptr, "Hello Dead Beef\n");
funcptr = print; /* actually a function */
call_the_printer(funcptr, "Hello Printer\n");
return 0;
}
NOTE Enable dynamic symbols for this to work
GCC/LLVM etc.
use -rdynamic or -Wl,--export-dynamic during the link process, so compile with:
gcc -o ex1 -rdynamic ex1.c
Windows
Windows does its own thing (as always) and I haven't tested any of these, but the basic concept should work:
Use GetModuleHandle and EnumCurrentProcess together to get loaded symbol information and run through the pointers in a loop to see they match any of the address therein.
The other way would be to use VirtualQuery and then cast mbi.AllocationBase to (HMODULE) and see if you get the path of your own binary back.
In c function pointers are no different than regular pointers and by standard they have one value that says the value should not be used and this is NULL.
The way you should work with pointers is to set them only to valid value or NULL. There is no other way you can be sure there is a OK value. And by definition every value that is not NULL should be considered valid.
Like pointed to in other comments and answers, there is not way to check a variable is initialized. That's why initializing vars to NULL and then checking is considered good practice.
If you really want to validate your function pointer is pointing to the correct place, you could export the function and load your pointer from the ELF symbols (see: http://gcc.gnu.org/wiki/Visibility)
Always check for null parameters first of all.
void print_client(client *c)
{
if ((c != NULL) && (c->print != NULL))
{
c->print(c);
}
}
As for your question, nullify your client struct after it's been malloc'd. This way you can ensure that an unassigned function pointer shall indeed ==NULL.
client* create_client(void)
{
client *c = malloc(sizeof(client));
if (c != NULL)
{
memset(c, 0, sizeof(c))
}
return c;
}

Node v8 variable default NULL but reassign based on argument passed

I'm sure it's really basic but I haven't been able to find anything like it (perhaps I'm going about it completely the wrong way).. I'm trying to pass str to the 'call_to_c_lib_func' function which takes either NULL or a string (char*).
#include <stdio.h>
#include <string.h>
#include <v8.h>
void test(const v8::FunctionCallbackInfo<Value>& args) {
char *str = NULL;
if (!args[3]->IsNull() && !args[3]->IsUndefined()) {
String::Utf8Value arg_str(args[3]->ToString());
str = *arg_str;
}
// Following function takes either NULL or char*
call_to_c_lib_func(str);
}
Edit: Post originally contained simplified C code for this which didn't really help explain the problem, hopefully this clarifies it a bit.
Your post doesn't ask a question or explain what problem you are having with the code. So I am assuming you ran the code exactly as posted and sometimes the call to the function behaves oddly or crashes.
Your existing code fails because:
String::Utf8Value arg_str(args[3]->ToString());
is inside a { code block } but you try to access its contents after that code block has exited (and therefore after arg_str has been destroyed).
Instead you could write:
String::Utf8Value temp;
char *str = NULL;
if (!args[3]->IsNull() && !args[3]->IsUndefined())
{
temp = args[3]->ToString();
str = *temp;
}
call_to_c_lib_func( str );
Of course there are many ways to skin a cat, just watch out when using v8::String that you do not use the result of operator* after the string has been destroyed, because it returns a pointer to the content of the string.
NB. I'm not familiar with V8 so there may be a more elegant way of accessing args[3]'s string data that neither of us is aware of.

C structure initialization before using it?

I do not understand why i have to initialize my structure before using it, i get this error in my code, i know it works if i use pointers or if i initialize the structure members, but why it does not work in this way ?
#include <stdio.h>
typedef struct human{
char name[20];
int age;
} student;
void function(student ){
printf("It's not working");
}
int main(){
student a;
function(a);
return 0;
}
I get this
Debug Error!
File: Run - Time Check Failure #3 - The variable 'a' is being used without being initialized. (Press Retry to debug the application)
and i do not get the message from my function on output
You get this error, because your debugger detect, that you are sending unitialized variable to the function. It doesn't know, what will you do with it inside of the function, so it warns you. You can see, that if you run program in release, no error will occur. Easiest solution for you, if you know, that you will initialize it lately to correct values, is just to initialize it, when creating student a = {0};
You are passing the object a by value to function. As C has only value-semantics, it can only copy values in this case. So, you initialise the parameter (even if your implementation doesn't care about the parameter) with an unitialised object, wich requires reading from that object. This is undefined behaviour, hence the compiler informs you that you are doing something illegal.
If you pass the object via a pointer, you still pass-by-value, but the value being copied is the pointer. Hence you don't have to read the actual value and your compiler wont complain.
Observe:
void flat(student s) {
s.age = 20;
}
void ptr(student* s) {
s->age = 20;
}
int main() {
student s = {"Eve", 0};
// { s.age == 0 }
flat(s);
// { s.age == 0 } --- still the same, no change
ptr(&s);
// { s.age == 20 } --- now it has changed
}

C passing char array to function, compute with another char array and copy

I would like to do something like that :
#include <stdio.h>
char * myfunction(char * in);
void myfunction2(char * in, const char ** content);
int main(){
char * name="aName";
char * result = myfunction(name);
return 0;
}
char * myfunction(char * in) {
const char *test = NULL;
myfunction2(in, &test);
return test; // I would like to return the value of test
}
void myfunction2(char * in, const char ** content) {
char input[1024];
//do some stuff to fill input
*content = input;
}
But I'm not able to do it, some weird char are printed instead sometimes...
Thank you for your reply, I understand it well now, but I'm stuck on another side of my problem. I didn't write precisely my use case, so I edited it to be complete.
The most glaring things wrong in this code are:
Implicit declaration of myfunction as int myfunction();
Incorrect const-ness of your pointers.
No return value provided for main()
Implicit declaration of myfunction as int myfunction();
This is easy enough to solve, and your compiler should be barking loudly at you when this happens. As a legacy feature of C, when a function call is encountered where no formal declaration, either by prototype or definition, is known, the function is assumed to return int and accept a variable number of parameters. Therefore in main() your call is assumed to be to a function that looks like this:
int myfunction();
Later when the real myfunction is encountered, at a minimum your compiler should scream at you with warning about how the declaration doesn't match the expected type (because by this time it thinks it is int myfunction()). Even then, however, the call should still go through, but it is terrible practice to rely on this. Properly prototype your functions before use.
Incorrect data types for all your pointers.
The string literal in your function is not bound to local array space. It is a read-only data buffer sitting in a read-only segment somewhere in your program's data blocks. The correct declaration is this:
const char *test = "mytest";
but that has the ripple effect of requiring changes to the rest of this code, which you'll see in a moment.
No return value provided for main()
Be definitive in your conclusion of main(). Apparently C99 allows you to skip this and implementation is supposed to return 0 for you. Don't give them that joy; seize it yourself.
Addressing all of the above...
#include <stdio.h>
void myfunction(const char** in);
int main()
{
const char *result = NULL;
myfunction(&result);
printf("in main() %p : %s\n", result, result);
return 0;
}
void myfunction(const char** in)
{
const char* test = "mytest";
printf("in myfunction() %p : %s\n", test, test);
*in = test;
}
Output (varies by implementation)
in main() 0x8048580 : mytest
in myfunction() 0x8048580 : mytest
See it live.
It looks good to me. May I suggest giving it a prototype or moving your myfunc() definition before main(). Also assigning a value to result when it is declared. That will give you a better idea of what is going on if the function is not doing what you expect.
For some reason, the other answers just pointed out technical detail that's wrong, but failed to notice what is really wrong: You are returning the address of an array on the stack. But when the function returns, accessing that array becomes undefined behavior. Other code may freely overwrite the memory, leaving the worst possible garbage in it, or, conversely, writing to the memory behind the returned pointer may trash any vitally important variable of some other, entirely unconnected parts of the code.
If you want to return a pointer, you must either return a pointer to a static object, or you must return a pointer to something on the heap. Here is the static case:
char* foo() {
static char staticArray[1024];
return staticArray;
}
Using static here guarantees that the memory reserved for staticArray[] will remain reserved for it throughout the execution of your program. There are, however, three downsides of this:
the array size is fixed at compile time
this is generally not multithreading safe since all threads will use the same globally allocated memory
you generally cannot expect the data behind the returned pointer to remain intact across a function call. Consider this code:
void bar() {
char* temp = foo();
temp[0] = 7;
}
void baz() {
char* temp = foo();
temp[0] = 3;
bar();
//now temp[0] is 7 !
}
This might be desirable in some rare cases, however, in most it's not.
So, if you want to be able to freely use the memory behind the returned pointer, you have to malloc() memory for it (and free() it afterwards, of course). Like this:
char* foo(int size) {
return malloc(size);
}
void baz() {
char* sevenBytes = foo(7);
//Do something with seven bytes
free(sevenBytes);
}
void bar() {
char* threeBytes = foo(3);
threeBytes[0] = 3;
baz();
assert(threeBytes[0] == 3); //baz() worked on it's own memory
free(threeBytes);
}
In the case of string handling, there is a number of handy functions available in the POSIX-2008 standard that do the memory allocation for you, among them strdup() and asprintf(). Here are some usage examples:
int main() {
char* hello = strdup("Hello");
char* greeting;
if(0 > asprintf(&greeting, "%s World!\nMemory for hello was allocated at %llx", hello, (long long)hello)) {
//error handling
}
printf(greeting);
free(hello);
free(greeting);
}
This will print something like:
Hello World!
Memory for hello was allocated at c726de80

Returning local data from functions in C and C++ via pointer

I have argument with my friend. He says that I can return a pointer to local data from a function. This is not what I have learned but I can't find a counterargument for him to prove my knowledge.
Here is illustrated case:
char *name() {
char n[10] = "bodacydo!";
return n;
}
And it's used as:
int main() {
char *n = name();
printf("%s\n", n);
}
He says this is perfectly OK because after a program calls name, it returns a pointer to n, and right after that it just prints it. Nothing else happens in the program meanwhile, because it's single threaded and execution is serial.
I can't find a counter-argument. I would never write code like that, but he's stubborn and says this is completely ok. If I was his boss, I would fire him for being a stubborn idiot, but I can't find a counter argument.
Another example:
int *number() {
int n = 5;
return &n;
}
int main() {
int *a = number();
int b = 9;
int c = *a * b;
printf("%d\n", c);
}
I will send him this link after I get some good answers, so he at least learns something.
Your friend is wrong.
name is returning a pointer to the call stack. Once you invoke printf, there's no telling how that stack will be overwritten before the data at the pointer is accessed. It may work on his compiler and machine, but it won't work on all of them.
Your friend claims that after name returns, "nothing happens except printing it". printf is itself another function call, with who knows how much complexity inside it. A great deal is happening before the data is printed.
Also, code is never finished, it will be amended and added to. Code the "does nothing" now will do something once it's changed, and your closely-reasoned trick will fall apart.
Returning a pointer to local data is a recipe for disaster.
you will get a problem, when you call another function between name() and printf(), which itself uses the stack
char *fun(char *what) {
char res[10];
strncpy(res, what, 9);
return res;
}
main() {
char *r1 = fun("bla");
char *r2 = fun("blubber");
printf("'%s' is bla and '%s' is blubber", r1, r2);
}
As soon as the scope of the function ends i.e after the closing brace } of function, memory allocated(on stack) for all the local variables will be left. So, returning pointer to some memory which is no longer valid invokes undefined behavior.
Also you can say that local variable lifetime is ended when the function finished execution.
Also more details you can read HERE.
My counter-arguments would be:
it's never OK to write code with undefined behavior,
how long before somebody else uses that function in different context,
the language provides facilities to do the same thing legally (and possibly more efficiently)
It's undefined behavior and the value could easily be destroyed before it is actually printed. printf(), which is just a normal function, could use some local variables or call other functions before the string is actually printed. Since these actions use the stack they could easily corrupt the value.
If the code happens to print the correct value depends on the implementation of printf() and how function calls work on the compiler/platform you are using (which parameters/addresses/variables are put where on the stack,...). Even if the code happens to "work" on your machine with certain compiler settings it's far from sure that it will work anywhere else or under slightly different border conditions.
You are correct - n lives on the stack and so could go away as soon as the function returns.
Your friend's code might work only because the memory location that n is pointing to has not been corrupted (yet!).
As the others have already pointed out it is not illegal to do this, but a bad idea because the returned data resides on the non-used part of the stack and may get overridden at any time by other function calls.
Here is a counter-example that crashes on my system if compiled with optimizations turned on:
char * name ()
{
char n[] = "Hello World";
return n;
}
void test (char * arg)
{
// msg and arg will reside roughly at the same memory location.
// so changing msg will change arg as well:
char msg[100];
// this will override whatever arg points to.
strcpy (msg, "Logging: ");
// here we access the overridden data. A bad idea!
strcat (msg, arg);
strcat (msg, "\n");
printf (msg);
}
int main ()
{
char * n = name();
test (n);
return 0;
}
gcc : main.c: In function ‘name’:
main.c:4: warning: function returns address of local variable
Wherever it could been done like that (but it's not sexy code :p) :
char *name()
{
static char n[10] = "bodacydo!";
return n;
}
int main()
{
char *n = name();
printf("%s\n", n);
}
Warning it's not thread safe.
You're right, your friend is wrong. Here's a simple counterexample:
char *n = name();
printf("(%d): %s\n", 1, n);
Returning pointer to local variable is aways wrong, even if it appears to work in some rare situation.
A local (automatic) variable can be allocated either from stack or from registers.
If it is allocated from stack, it will be overwritten as soon as next function call (such as printf) is executed or if an interrupt occurs.
If the variable is allocated from a register, it is not even possible to have a pointer pointing to it.
Even if the application is "single threaded", the interrupts may use the stack. In order to be relatively safe, you should disable the interrupts. But it is not possible to disable the NMI (Non Maskable Interrupt), so you can never be safe.
While it is true that you cannot return pointers to local stack variables declared inside a function, you can however allocate memory inside a function using malloc and then return a pointer to that block. Maybe this is what your friend meant?
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char* getstr(){
char* ret=malloc(sizeof(char)*15);
strcpy(ret,"Hello World");
return ret;
}
int main(){
char* answer=getstr();
printf("%s\n", answer);
free(answer);
return 0;
}
The way I see it you have three main options because this one is dangerous and utilizes undefined behavior:
replace: char n[10] = "bodacydo!"
with: static char n[10] = "bodacydo!"
This will give undesirable results if you use the same function more than once in row while trying to maintain the values contained therein.
replace:
char n[10] = "bodacydo!"
with:
char *n = new char[10];
*n = "bodacydo!"
With will fix the aforementioned problem, but you will then need to delete the heap memory or start incurring memory leaks.
Or finally:
replace: char n[10] = "bodacydo!";
with: shared_ptr<char> n(new char[10]) = "bodacydo!";
Which relieves you from having to delete the heap memory, but you will then have change the return type and the char *n in main to a shared_prt as well in order to hand off the management of the pointer. If you don't hand it off, the scope of the shared_ptr will end and the value stored in the pointer gets set to NULL.
If we take the code segment u gave....
char *name() {
char n[10] = "bodacydo!";
return n;
}
int main() {
char *n = name();
printf("%s\n", n);
}
Its okay to use that local var in printf() in main 'coz here we are using a string literal which again isn't something local to name().
But now lets look at a slightly different code
class SomeClass {
int *i;
public:
SomeClass() {
i = new int();
*i = 23;
}
~SomeClass() {
delete i;
i = NULL;
}
void print() {
printf("%d", *i);
}
};
SomeClass *name() {
SomeClass s;
return &s;
}
int main() {
SomeClass *n = name();
n->print();
}
In this case when the name() function returns SomeClass destructor would be called and the member var i would have be deallocated and set to NULL.
So when we call print() in main even though since the mem pointed by n isn't overwritten (i am assuming that) the print call will crash when it tried to de-reference a NULL pointer.
So in a way ur code segment will most likely not fail but will most likely fail if the objects deconstructor is doing some resource deinitialization and we are using it afterwards.
Hope it helps

Resources