I have a function that is supposed to read (in a very bad way) a file. I expect it to modify a struct that I pass as a parameter to store the things that it has to read. But when I call it, it throws a segmentation fault. I have a print as the first thing the function does, and it doesn't do it. So I guess I have a problem with the declaration of the function or something. I can't figure it out.
int main(int argc, char **argv){
//some parser here
struct client_config *config;
read_software_config_file(*config); //I also passed it as non pointer and & but nothing worked.
}
void read_software_config_file(struct client_config config){
printf("Hello"); //it breaks here
}
As someone pointed out I did this:
struct client_config config;
read_software_config_file(&config);
But it still shows me segmentation fault.
Here is a working example:
#include <stdio.h>
struct client_config
{
int data;
};
void read_software_config_file(struct client_config *config); // Forward Declaration
int main(int argc, char **argv)
{
struct client_config config; // Memory on stack. Use malloc/calloc for heap
config.data = 10; // Init data
read_software_config_file(&config);
printf("config.data = %d\n", config.data);
return 0;
}
void read_software_config_file(struct client_config *config)
{
printf("Hello\n");
config->data = 12;
}
I would generally advise to compile with -Wall -Wextra -pedantic to catch errors early.
You have to forward declare the function read_software_config_file (or include a header etc.) s.t. the compiler knows the signature when you call it in main.
As said in the comments you should take a pointer to the struct, s.t. it can be modified.
The output after running main is:
Hello
config.data = 12
When you declare any variable, pointer or not, without initializing it, it gets whatever is in memory as its current value. Some higher level languages may implicitly initialize all new values with "default" variables. You may have gotten used to this from previous programming experience; this is not the case in C.
If you use the * dereference operator on an uninitialized pointer, you are dereferencing whatever address is represented by the current value of the pointer, which is undefined behavior, and almost certainly going to cause an access violation.
You need to initialize your pointer to point to something; either an existing struct client_config, or new heap memory allocated with malloc or calloc.
Also, if your function really is meant to take a pointer to a struct client_config, the parameter should have a * operator on it as well.
Related
It seems there are many questions of the form "should I declare X?" but not this specific one. I hope it is ok to ask this.
The title says it all: why should I declare a pointer? Even better: there are risks if I do not declare the pointer? Consider the following examples:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <time.h>
#include <string.h>
void func(int *ptr);
int main (int argc, char **argv)
{
int a;
int *PTRa;
a = -1;
PTRa = &a;
func(PTRa);
printf("%d\n", a);
return 0;
}
void func(int *ptr)
{
*ptr = 1;
return;
}
I get a=1. In this case I would say the pointer is declared (and assigned as well): I have the line int *PTRa; (declaration) and the line PTRa = &a; (assignment). The results is correct. I don't get any warning.
Imagine now to replace the main with the following:
int main (int argc, char **argv)
{
int a;
a = -1;
func(&a);
printf("%d\n", a);
return 0;
}
Here I do not declare the pointer but just give the address of a to func. The result is correct and I don't get warnings.
My understanding is that the two approaches are identical: func always gets the same input, the address of a. I would even dare to say that I feel the second approach to be better, as I feel it to be clearer and I feel the variable PTRa to be useless and somewhat redundant. However, I always see codes where the first approach is used and I have the feeling I will be told to do so. Why?
You are correct: there's no point in declaring a pointer in your example. A pointer is just a variable that holds an address. The cleaner approach is to pass directly the address of the variable: func(&a) instead of doing one extra step and declaring PTRa.
Note that not all cases are this simple. For example, if you want to have an array of ints, but you want to be able to grow that array dynamically because you don't know how big it should be you have to declare a pointer:
int count = ...; // get the count from the user, from a file, etc
int *list_of_ints = malloc(sizeof(int) * count);
if (list_of_ints == NULL)
{
// malloc failed.
printf("Not enough memory!\n");
exit(1);
}
// Now `list_of_ints` has enough space to store exactly `count` `int`s
EDIT: as #paulsm4 pointed out in a comment, the question Why use pointers? is a great source of information related to this topic.
EDIT 2: one good reason to want a pointer to the address of a variable might be that you want a pointer inside a structure or array:
struct foo
{
int x;
};
struct bar
{
int y;
struct foo f;
};
struct bar b;
struct foo *ptr_foo = &b.f;
You can now work more easily with b.f because you're just working with a struct foo.
In this case there's no benefit in creating a separate pointer variable.
It might be necessary in more complex cases, just like it's sometimes necessary to create variables of any other type.
From the title, I thought you're talking about pointer type, but actually, you are asking if declaring a variable is needed.
Variable is a piece of memory, storing some numbers(bytes), and the type of the variable, indicating how you and your program interpret those bytes: integer? float? character? etc.
Pointer is the memory address, it could be of a variable, or a function, or something else.
A variable of pointer is a small area in the memory, storing the address of other(or even same) memory.
You decide if you need an extra variable to store the pointer. It's the same to the decision that if you want a variable to store an integer:
int v = -1;
abs(v); // use variable
abs(-1); // use constant
What does this code mean?
char code[] = "bytecode will go here!";
int main(int argc, char **argv) {
int (*func)(); /* This is pointer to function */
func = (int (*)())code; /* What does this line mean? */
(int)(*func)(); /* Calling function by pointer */
}
func = (int (*)()) code;
code, being an array, is implicitly converted to a pointer to its first element (it decays to such a pointer). This pointer is then cast to a pointer to a function.
This cast causes undefined behaviour. But "most of the time", it will probably result in a function pointer pointing to the address of the array. When you call it, then control jumps to this array. If it contains string data, you'll most likely get an invalid opcode or a segmentation fault. But if that array contains some user input a malicious user could've put (compiled) code into it, doing all sorts of funny (or less funny) stuff.
As an example, consider the above code running in some sort of server, being fed user input over some website. Then one could replace the program with, for example /bin/sh and thus gain shell access on that server.
What you're seeing there is an example of type punning.
void print_hello()
{
printf("hello");
}
int main()
{
void (*hello_func_ptr)() = &print_hello;
//we convert what the function points to to a string of "byte code"
char *func_byte_code = (char *)hello_func_ptr;
// prints out byte code of the function
printf(func_byte_code);
// we cast the string byte code to a function pointer
void (*func_from_byte_code)() = (void (*)())func_byte_code;
// we call the function we got from casting the byte code to a function pointer
(*func_from_byte_code)(); // prints "hello"!
return 0;
}
What your function does is taking the byte code string and convert it back to a function pointer like we've done above. You can then call the function by dereferencing the pointer and calling it by adding the parentheses and any parameters the function takes.
Now of course, you shouldn't need to do things like that in regular programming but seldom in peculiar cases.
This is a sample of shell code.
here:https://en.wikipedia.org/wiki/Shellcode
func = (int (*)()) code; /* What does this line mean? */
func is a function point,it point to the address of "code array".
when the func be called,program will be jump to the address of array.
I want to store result of type char in pointer which I'm passing as argument of function. Like this:
#include<stdio.h>
void try(char *);
int main()
{
char *result;
try(result);
printf("%s",result);
return 0;
}
void try(char *result)
{
result="try this";
}
But I'm getting result : (null)
Could someone tell me what's wrong here?
Your syntax only sends the pointer to the function. This allows changing the data the pointer points to, but not the pointer itself.
You would need to have
void try(char **result)
and call it
try(&result);
to change the actual pointer.
Another way is to copy data into the memory pointed by the pointer, but then you need to know there is enough memory available. Depends on the actual use case how to do it properly. You might use
strcpy(result, "what you want");
but then you really have to know that the memory pointed by result can handle 14 chars (remember the NULL in the end). In your current code you don't allocate memory at all for result, so this will invoke undefined behaviour.
The reason you're seeing NULL is because your compiler decided to initialize non-assigned pointers to NULL. Another compiler might initialize them to random values.
Also about terminology, you're not storing type char into a pointer. You may have a pointer pointing to a char, or in this case to a C type string, which is an array of chars.
You are creating another variable result inside try function.
Try printing result inside try function. It will work then.
If you really want to print inside main then try this -
#include<stdio.h>
void try(char **);
int main()
{
char *result;
try(&result);
printf("%s",result);
return 0;
}
void try(char** result)
{
*result = "try this";
//printf("%s\n",result);
}
Or if you don't want to get into double pointers, then this will work:
#include<stdio.h>
char* try(char *);
int main()
{
char *result;
result = try(result);
printf("%s",result);
return 0;
}
char* try(char* result)
{
result = "try this";
return result;
}
Also another way (no dynamic memory):
#include<stdio.h>
void try(char *);
int main()
{
char result[100] = {0};
try(result);
printf("%s",result);
return 0;
}
void try(char *result)
{
strcpy(result,"try this");
}
Note: When you say you got null, that doesn't mean anything - actually you had undefined behaviour there - because result was not initialized. I guess you invoked UB even before trying to print result, namely when you passed it to try. Because copy would be made in that method of the pointer, which would try to read value of original pointer - reading uninitialized variables is undefined in C. Hence always initialize your variables in C.
I have two files, main.c and main2.c. My experience tells me that they should do exactly the same, but they do not.
main.c declares a global variable outside the main routine. Then, inside the main routine, a pointer is declared and defined to point to that global variable. The global variable is changed, and the value of the local variable is printed to screen.
main2.c does the same, but convolutes local-to-global definition and change of global variable value into another function, change_number.
I cannot understand why this approach fails. main.c and main2.c are the boiled down results from a few hours of bugs fixing, documentation and tutorial reading and, obviously, reading here on SO.
My understanding of pointers is what I would call rudimentary: It points to a memory location. In case of a regular variable, the pointer would point to the memory location of that variable. Several pointers can point to the same memory location, but one pointer cannot point to several locations.
There's no such thing as pass-by-reference in C, but, as far as I know, this is not pass by reference since all variable and pointers are defined outside the function. Please enlighten me.
//File: main.c
#include <stdio.h>
#include <stdlib.h>
int global_number;
int main() {
int *local_number;
local_number = &global_number;
global_number = 9;
printf("local_number = %d\n", *local_number);
return 0;
}
Output: "local_number = 9". This is the expected result.
//File: main2.c
#include <stdio.h>
#include <stdlib.h>
int global_number;
void change_number(int *number) {
number = &global_number;
global_number = 9;
}
int main() {
int *local_number;
change_number(local_number);
printf("local_number = %d\n", *local_number);
return 0;
}
Output: "Segmentation fault". This is obviously not intended. The code runs fine right up until printf().
you never initialize local_number in the second program. It does not point anywhere, and will crash when accessed. Try
int *local_number = &global_number;
then the value should change
To have change_number also initialize local_number, pass the address of local_number and change the pointed-to pointer:
void change_number( int **number ) {
*number = &global_number;
global_number = 9;
}
...
int *local_number;
change_number(&local_number);
Title pretty much sums this up. How come it's possible that i can assign a locally created Point a (in the function ReadPoint()) into a variable that's in a different scope. Doesn't the locally created Point a gets 'popped' away along with stack of function readPoint() ? What exactly is going on ?
struct Point readPoint(void)
{
struct Point a;
printf("x = ");
scanf("%lf",&b.x);
printf("y = ");
scanf("%lf",&b.y);
return a;
}
int main(int argc, char **argv) {
Point test = readPoint();
printPoint(test);
return 0
}
structs are no different to primitive types in this regard. It's exactly the same principle as:
int foo(void)
{
int x = 5;
return x;
}
int main(void)
{
int y = foo();
printf("%d\n", y);
}
The details of how this is achieved are implementation-dependent. But usually, the return value (whether it's an int or a struct) is placed onto the stack by the called function, and then the caller then can then access that stack location.
The struct is "copied", byte by byte, into test in main...just like returning an int from a function and assigning it to a variable.
This, however, wouldn't happen if you were returning a pointer to the struct and the dereferencing it and assigning (or something similar).
When returning, you'll create a copy of the object (with all members of the struct), but the local variable/object is still destroyed.
This will work unless you try to return a reference or pointer (in these cases your compiler should warn you about this stupid idea). This will work fine, unless you're trying to create a copy of something working with pointers.
In C++ this would include references too.
This is because on return from readPoint() all structure values are copied to another locally defined structure test. Structure a does not survive.
What you're seeing is structure assignment. Almost all modern compilers can handle this.