Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have a doubt in de-referencing the pointers
I wrote a simple code but i dont know the reason why it is failing in certain condition can someone pls tell what is the reason for it to fail. and if we have char *ptr = "stack overflow" then the compiler itself will allocate memory to it.
int main()
{
int *ptr = 10;
double *dptr = 111.111
printf("%d", *ptr); //will give segmentation violation as we are trying to access the content in location 10
printf("%d", ptr);//o/p will be 10
printf("%lf", dptr); // will give segmentation violation
printf("%lf", *dptr); // will give segmentation violation
}
int *ptr = 10;
double *dptr = 111.111
The problem lie in the above two lines.
ptr points to the address 10 and dptr is I don't know where it is pointing.
Dereferencing these pointers will certainly yield undefined behavior.. usually a segmentation violation fault.
Fix:
int main(){
int iVal = 10;
double dVal = 111.11;
int *ptr = &iVal;
double *dptr = &dval;
printf("%d", *ptr); // ok
printf("%p", (void *)ptr);// ok
printf("%p", (void *)dptr); // ok
printf("%lf", *dptr); // ok
return 0;
}
Theory: A pointer is a variable that holds address - or as Alexey Frunze says:
The C standard does not define what a pointer is internally and how it
works internally. This is intentional so as not to limit the number of
platforms, where C can be implemented as a compiled or interpreted
language.
A pointer value can be some kind of ID or handle or a combination of
several IDs (say hello to x86 segments and offsets) and not
necessarily a real memory address. This ID could be anything, even a
fixed-size text string. Non-address representations may be especially
useful for a C interpreter.
When you do
int *ptr = 10;
you tell the compiler that ptr is a pointer to the address 10. Dereferencing this address will cause undefined behavior and may cause a crash.
You would most likely want something like:
int ival = 10;
int *ptr = &ival;
Similar for the double pointer.
char *ptr = "stack overflow"
This buffer was allocated in TEXT SEGMENT hence there is no issue of dereferencing and getting the address but if you modify the data content its a voilation [Segmentation Fault]
Note:-
Please refer from online,how many segments will be created for a program (process) ?
[Generally, Heap Segment,Stack Segment,Data Segment & Text Segment]
The reason char *ptr = "stack overflow" works and int *ptr = 10 does not is that 10 is just the number 10, but "stack overflow" evaluates to a pointer to the characters.
String literals are special kinds of constants. The compiler puts the characters of the string somewhere in memory, and the value of the string literal is a pointer to those characters. Conversely, integer and floating-point constants are just their values; they are not pointers.
Related
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 6 years ago.
#include<stdio.h>
int* add(int *a, int *b){
int c = *a + *b ;
return &c;
}
int main(void) {
int a=3,b=2 ;
int *ptr = add(&a,&b); // doubt in this line as it returns 5
printf("%d",*ptr);
}
I have doubt in the line commented.
I am using Codeblocks IDE(GNU gcc compiler), and I was wondering that if the *ptr in my main is pointing to the address of c in the add function, then it should print garbage as after the function `add completes its execution, it's popped from the stack, and the memory should be deallocated for it in the stack . So technically, it should be pointing to garbage. Then how is it printing the correct value.
You have undefined behavior, as you are returning the address of a function-local variable. A good compiler with warnings enabled would tell you this.
When you have undefined behavior you don't get to complain about the results. There is no need to wonder why it gives you the "correct" result because it does not--it gives you some number which may or may not be correct depending on any number of factors you don't control.
I think this is undefined behavior. On my system this example crashed with a segmentation fault. When something is deallocated, it is possible that the pointer to that memory location is simply moved without zeroing out the memory.
This question already has answers here:
Why don't I get a segmentation fault when I write beyond the end of an array?
(4 answers)
Closed 7 years ago.
I'm actually learning C and I got a "problem".
I created a pointer to a structure with a char* and int with malloc(1).
The pointer works and I can edit structure children without problems.
I also created a pointer to a int (still with malloc(1)) and it works. Another thing is I didn't get core dump error when I tried to access *(pointer + 33780) (Core dump comes when the value is a bit higher) it worked, but default value was 0.
Thank you, that's not a "problem" but I'd like to know why is that doing like this.
Sorry for being the English's murderer.
EDIT : Here the code
struct Personne
{
char *name;
int age;
};
int main(int argc, char *argv[])
{
printf("%ld\n", sizeof(struct Personne));
struct Personne *testPoint = malloc(1);
printf("testPoint : %p\n", testPoint);
printf("testPoint : %p\n", testPoint->name);
testPoint->name = "UnNomInconnu";
testPoint->age = 20;
free(testPoint);
return 0;
}
Actually function malloc does not allocate a memory extent exactly of the size of 1 byte or of a similar small value. Usually the minimum size of an allocated extent is equal to the size of the paragraph that is to 16 bytes.
So if you will write for example
char *p = malloc( 1 );
then the actual size of the allocated extent can be equal to 16 bytes.
Nevertheles you should not rely on this feature becuase in general that is according to the C Standard this is undefined behaviour.
struct Personne *testPoint = malloc(1);
puts you into the realm of undefined behavior. Unfortunately UB can include "the program runs correctly in all test environments but fails in production at worst possible time" - and frequently does.
If you are on linux run your program under valgrind and/or electric fence. You will see why those tools exist.
You need:
struct Personne *testPoint = malloc(sizeof(*testPoint));
1 byte is not enough memory for your structure. The meaning of malloc() argument is the number of bytes. However, malloc() does not necessarily protect the memory beyond the allocated segment, so in some cases it is possible to overwrite the boundary without fatal consequences.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am making a game in c, and I get an error with a struct array which I have created.
typedef struct{
int type, level, x, y, w, h;
} Tile;
Tile *map[256];
Tile *t;
t->type = 0;
t->level = 0;
t->x = 0;
t->y = 0;
t->w = 0;
t->h = 0;
map[0] = t;
Once compiled, the program prints:
Segmentation fault (core dumped)
Defining a pointer does not automatically make that pointer to point to a valid memory location. A pointer, which is not allocated memory, is called as uninitialized pointer and cannot (shall we say, should not?) be de-referenced.
In your code,
t->type = 0;
and so on, you're de-referencing t which is not allocated memory. Hence, by de-referencing an unitialized pointer, you invoke undefined behavior. The segmentation fault is one of the many side-effects of the UB.
Solution: You need to allocate memory to t before you can actually dereference it. Maybe you can have a look at malloc() and family of functions to get the memory allocation done.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I am trying to simulate the null pointer undefined behaviour.
What changes should be made in the below code to introduce null pointer undefined behaviour.
void foo( int * d )
{
printf("hello\n");
}
int main(void)
{
int a = 7 ;
int *b = malloc(sizeof(int)) ;
foo(b) ;
}
Dereferencing a NULL pointer (or some address outside your current address space, often in virtual memory) in C is not an exception, but some undefined behavior (often a segmentation fault). You really should avoid UB.
By definition of undefined behavior, we cannot explain it without going down into very specific implementation details (compiler, runtime, optimization, ASLR, machine code, phase of the moon, ...).
The malloc library function can (and does) fail. You should always test it, at least as:
int *b = malloc(sizeof(int));
if (!b) { perror("malloc of int"); exit(EXIT_FAILURE); };
To trigger failure of malloc (but very often the first few calls to malloc would still succeed) you might lower the available address space to your program. On Linux, use ulimit in the parent shell, or call setrlimit(2).
BTW, you could even link with your own malloc which is always failing:
// a silly, standard conforming, malloc which always fail:
void* malloc(size_t sz) {
if (sz == 0) return NULL;
errno = ENOMEM;
return NULL;
}
The C programming language does not have exceptions. C++ (and Ocaml, Java, ....) does (with catch & throw statements). Raising an exception is a non-local change of control flow. In standard C you might use longjmp for that purpose. In C++ dereferencing a nullptr is UB (and does not raise any null-pointer exception which does not exist in C++).
Based on your code, we can simulate Null Pointer UB like this,
#include<stdio.h>
void foo( int * d )
{
printf("hello, it is %d\n", *d);//dereference d (produces "Segmentation fault" if d is NULL)
}
int main(void)
{
int a = 7 ;
int *b = NULL; // simulate failed to malloc(sizeof(int))
foo(&a); // output is "hello, it is 7"
foo(b); // will trigger something like "Segmentation fault"
}
As pointed by #Basile Starynkevitch, there are no exceptions in C, so here it would be more accurate to say "NULL pointer UB(Undefined Behaviour)" compared to "NULL pointer exception".
Here's how to dereference a null pointer:
int *b = 0;
*b = 3;
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
What I currently have is a simple function that basically just reassigns pointers given the parameter pointer but I'm getting an error saying that I'm using one of the variables uninitialized. Here's what I have and the error is being thrown on the line *x = *k;
float * program(const int *k)
{
float *x;
*x = *k;
return x;
}
This has got to be a really simple fix, but I feel like I'm just missing it.
Here's what your code is doing:
float * program(const int *k)
{
// declare a pointer to a float, but don't initialize it,
// so it is not actually pointing anywhere specific yet.
float *x;
// Put the value pointed at by k into the location pointed at by x
// But wait - we don't know where x is pointing, so this is BAD!
*x = *k;
return x;
}
And that is why your compiler is complaining.
It looks as if you're making a cast into a function, or achieving a cast via a function.
The compiler is correct that x is not initialized, so assigning to *x leads to undefined behaviour (and the compiler warning you are getting). This code might be what you want:
const float *program(const int *k)
{
const float *x = (float *)k;
return x;
}
You need the cast — unless you are compiling with way, way, way too many warnings disabled. Note that this is still giving you undefined behaviour, but it is a somewhat different form of undefined behaviour — with most systems, this code will reinterpret the int pointer as a float pointer and you'll get more or less sane results. With the uninitialized variable, you simply cannot tell what will happen; it is much worse to dereference an uninitialized pointer.
Keep in mind that:
A pointer is a variable that contains memory address. Other words, content of a pointer is memory address. To utilize the address, you have to request the system reserve it for you via malloc, calloc...
Now let's examine your code:
- Third line: float *x; --> you declares a pointer x pointing to a memory address which will be used to store (some) float number(s). However the address is not allocated yet so it would be anywhere in your system memory and certainly is not reserved for you only.
- Fourth line: *x = *k; --> you access a memory allocation that hasn't been allocated --> a running error. If you are lucky (there is no program access this memory), you can get value of k.
What you should do here is to allocate a memory reserved for x by calling malloc, calloc, ...
If k points to only 1 int number, your code should be:
float *program(const int *k)
{
float *x;
x = (float *)malloc(sizeof(float));
*x = *k;
return x;
}
And if k points to an arry of int numbers, try to figure out by yourself :)