I have created this code to test one error, that I get in my main code, and it shares the same problem. I'm always getting either segmentation fault or corrupted data (zeros or strange numbers).
Here is the code:
int *p=NULL;
int func (int **point);
int main() {
int num = 5647;
p = malloc(sizeof(int)*2);
p[0] = num;
p[1]= 657;
printf("%d\n", p[0]);
printf("%d\n", p[1]);
func(&p);
printf("%d\n", p[0]);
printf("%d\n", p[1]);
printf("%d\n", p[2]);
printf("%d\n", p[3]);
return 0;
}
int func (int **point){
*point = realloc(*point,sizeof(int)*4);
if (*point==NULL){
printf("\n abort \n");
exit(0);
}
*point[0] = 867;
*point[1]= 777;
*point[2] = 67;
*point[3]= 77;
}
I'm getting the segmentation fault on the *point[1]=777;. If I'm trying to do like point[1]=777; I'm getting wrong data. With any changes in int func (int **point); or func(&p); I'm getting segmentation fault on realloc.
Please advise, I have read information about double pointers and tried to follow all solutions I found, but every time I'm getting this error.
Your problem is operator precedence, change *point[0] to (*point)[0] and so forth.
What you have right now is *(point[0]). You treat a pointer to a single element as a pointer to multiple consecutive elements and then dereference some indeterminate value as an address. This results in undefined behavior, which luckily for you manifests as a crash.
After the change you first dereference point and then use that address to index into consecutive elements you allocated.
Two suggestions for improvement:
Don't assign the result of realloc directly to *point. If the call fails, then you leak the original memory. Assign it to a temporary first for verification.
Also, try not to repeat types. Instead of sizeof(int) try for sizeof(**point), i.e whatever the output buffer is supposed to point at. That way you won't have silent errors in your code if you change the type from int to something else.
void *point_check = realloc(*point,sizeof(**point)*4);
if (point_check == NULL){
printf("\n abort \n");
exit(0); // If this ever returns instead of exit, `*point` will not leak
}
*point = point_check;
Related
I'm having an issue understanding why I can't make the re-assignment for lastPrefix, on the line specified it gives me a segment fault. I appear to be missing something fundamental.
char * somefunc(char ** strs, int numStrings)
{
char * lastPrefix;
printf("%d\n", *(strs[0]+0));
printf("%d\n", *(strs[1]+0));
printf("%d\n", *(strs[2]+0));
printf("%d\n", *(strs[0]+1));
printf("%d\n", *(strs[1]+1));
printf("%d\n", *(strs[2]+1));
printf("%d\n", *(strs[0]+2));
printf("%d\n", *(strs[1]+2));
printf("%d\n", *(strs[2]+2));
printf("%d\n", *(strs[0]+0));
printf("%d\n", *(strs[1]+0));
printf("%d\n", *(strs[2]+0)); // ALL IS WELL
*lastPrefix = *(strs[1]+0);
*lastPrefix = *(strs[2]+0);
*lastPrefix = *(strs[0]+1); // WILL SEGMENT FAULT HERE
*lastPrefix = *(strs[1]+1);
*lastPrefix = *(strs[2]+1);
}
int main()
{
char * strs[] = {
"flower", "flow", "flight"
};
char * res = somefunc(strs, SIZEOF(strs));
}
Could I also ask for a good reference for C pointers?
When you create any variable, whether it's pointer or data, the initial value of the variable will be some garbage or 0. In your case,
char *lastPrefix;
Is such a variable, which contains some garbage value. You have to give it a valid value using malloc() or something like that. Or else, when you de reference it(*), it might points to some inaccessible or even nonexistent memory location. Maybe it points to the middle of your code. Maybe it points to NULL. Memories like that is inaccessible in userspace. So, windows(or linux) kills your program.
What you want to do:
char *lastPrefix;
lastPrefix=malloc(101); //holds strings upto 100 characters
The malloc() will allocate value into your variable from heap and the program should work okay.
Just remember to free the memory at the end: free(lastPrefix);
int *ptr; // pointer variable declaration */
int kk; // actual variable declaration */
*a = 11; // `a` pointing to unknown memory address and accessing this will give segmentation fault/
a = &kk; *a = 11 // This is valid. store address of `kk` in pointer variable */
Similarily, in your code lastPrefix points to an unknown address, accessing it will give you segmentation fault.
I can't find any errors in the code below, but every time I run it, the compiler (Xcode) returns hread 1: EXC_BAD_ACCESS (code=2, address=0x10000a025). I'm wondering if any of you have any answers to the problem.
int main(){
int *p,b;
b=3;
(*p)=38;
b=(*p)+10;
*p=b+1;
printf("b,p=%d %d\n",b,*p);
}
Thank you!
You are trying to dereference an uninitialized variable. Initialize it and it will work.
For example:
int *p,b,c=38;
b=3;
p=&c;
// now you can dereference it because it is initialized.
// now when you do (*p) = 3; // you will be changing c to 3
Or you can do this:
int *p;
if (!(p=malloc(sizeof(*p))) return 1; // In case of failure of malloc
(*p) = 38; // valid
// you will also need to free the memory when you are done
free(p);
I want to allocate memory dynamically inside a function. The function is named func_1 and is declared as follows:
int func_1(int **destination);
Here destination is a pointer to a pointer. This pointer contains the address of the pointer to which I want to allocate memory dynamically inside the function.
The function func_1 has the following code:
void func_1(int **destination)
{
*destination = (int*)malloc(sizeof(int) * 10);
for(int i = 0 ; i < 10 ; i++)
{
*destination[i] = i; //segmentation fault comes HERE
}
}
Below is my main() function:
int main()
{
int *pointer;
func_1(&pointer);
return 0;
}
When I try to run this program, I get a segmentation fault (SIGSEGV) error. I used GDB to locate the source of this fault, and it turned out that the line inside the for loop is the culprit for this error.
Please note that I wish to retain the values I have assigned to the dynamically allocated memory inside the function, once the function exits, and that's the reason due to which I have passed the address of the pointer to which I want to allocate memory dynamically.
I want to know:
Why am I getting this error ?
How can this be fixed ?
Thanks for help !
[] (array subscripting) operator has precedence 2
* (dereference) operator has precedence 3
In your code *destination[i] means the same as *(destination[i]). This value is uninitialized and it leads to segmentation fault.
If you will use explicit priority of operation (*destination)[i] you will get the expected result.
void func_1(int **destination)
{
*destination = (int*)malloc(sizeof(int) * 10);
for(int i = 0 ; i < 10 ; i++)
{
(*destination)[i] = i; //no segmentation fault
}
}
you can read more about precedence here
Full code:
#include <stdio.h>
#include <stdlib.h>
void func_1(int **destination)
{
*destination = (int*)malloc(sizeof(int) * 10);
for(int i = 0 ; i < 10 ; i++)
{
(*destination)[i] = i;
}
}
int main()
{
int *pointer;
func_1(&pointer);
return 0;
}
Why am I getting this error ?
You are overwriting the destination pointer instead of assigning the value returned by malloc to the pointer pointed to by the destination pointer.
Instead of *destination = (int*)malloc(sizeof(int) * 10) you should type **destination = malloc(sizeof(int) * 10).
Instead of *destination[i] = i you should type (**destination)[i] = i.
In C, the array subscript operator [] has a higher precedence than the indirection operator *. In addition to that, the former is left-to-right associative, while the latter is right-to-left associative.
In your case this means that you need to type (**destination)[i] = i; instead of **destination[i] = i, because otherwise the [i] will be evaluated before the ** and you end up indirecting a wild pointer (which will cause a segmentation fault extremely likely in the general and absolutely certainly in this case, since you are referencing a null pointer when i == 0).
How can this be fixed ?
The "just make it work" fix is the one I presented above.
However, that does not address the fundamental issue with your code, which is that it is unnecessarily complicated. Using a pointer to a pointer is very error-prone and should be avoided. Indeed, there is no need to use one at all in this case.
The following does exactly what you want without all the unnecessary complexity:
int* func_1()
{
int* destination = malloc(sizeof(int) * 10);
for (int i = 0; i < 10; ++i)
{
destination[i] = i;
}
return destination;
}
int main()
{
int* pointer = func_1();
free(pointer);
return 0;
}
Please note that I wish to retain the values I have assigned to the dynamically allocated memory inside the function, once the function exits, and that's the reason due to which I have passed the address of the pointer to which I want to allocate memory dynamically.
As I demonstrated above, there is no reason to pass a pointer to the pointer to the function. Memory allocated with malloc is yours to use forever , you just need to keep track of it and release it with a call to free when you no longer need it. How you keep track of the memory doesn't matter - simply returning a pointer is enough in this case. Modifying pointer inside func_1 rather than catching the function's return value provides no additional benefit and only serves to make the code more complicated than it needs to be.
I get the impression that you are somewhat confused about pointers, so I recommend that you revise the subject. Here is a quite clear explanation regarding pointers that also covers pointers to pointeres (and pointers to pointers to pointers): How do pointers work in C?
Read more:
Operator Precedence and Associativity in C
What is a segmentation fault?
i am using gcc compiler on ubuntu 14.04 LTS for compilation of following c program
#include<stdio.h>
void main()
{
int *a,*b;
*a=2;
*b=3;
printf("\n printing address.....\n address of a = %d \n address of b = %d \n",a,b);
printf("\n\n printing values ..... \n value of a = %d \n value of b = %d \n",*a,*b);
}
and when i run above program than i get following in output
output: Segmentation fault (core dumped)
please suggest where i am doing wrong.
thanks
You're declaring and using pointers (pointed-to memory), without allocating space for them.
Just declaring:
int *a;
doesn't give you memory to use, this just declares a variable that can reference memory.
The pointer, once declared, is un-initialized, and will point to some part of memory that doesn't belong to you. Using that memory - in your case, putting a value there - will result in undefined behavior; you see a core dump when you touch that memory.
In order to get some space to use, learn about malloc:
int *a = NULL; // good practive to initialize/reset pointers to NULL
// malloc will give you space for 1 int, and a will point to that new space
a = malloc(sizeof(int));
if (a != NULL) // malloc returns NULL in the event of a failure
{
// a is non-NULL so now we can use the memory pointed-to:
*a = 5;
// other code that uses a goes here:
...
// and when you're finished with a give the memory back:
free(a);
a = NULL;
}
When you declare a pointer
int* p;
it is similar as declaring an integer variable:
int v;
the contents of v is uninitialized - same with p - it is also uninitialized so when you use p e.g. *p you may be dereferencing an address anywhere in memory, even in read-only memory. Instead you need to initialize the variables.
int v = 0;
int* p = &v; // p points to v in memory
I have two questions about dynamic allocated array. I have looked up some similar questions but still didn't find the answer.
Pass by value
Basically, I write two functions, one for allocation and another for free memory. When I pass the array pointer by value, the allocation function didn't work (as expected) but the free function works. And in my naive understanding, even if we pass the array pointer by value, the allocation should still work since it allocates a memory at the same memory address the value represented. And if we refers to that address later, regardless of the variable name, we should be able to find that space. This is the code:
void main()
{
int * array;
allocation(array);
deallocation(array);
}
void allocation(int * result)
{
result = malloc(8293 * sizeof(result));
}
void deallocation(int * result)
{
free(result);
}
For deallocation test, I declared int * array = malloc(23123* sizeof(int)) in the main function instead of using allocation function. Again, the deallocation works.
Out of range access.
void main()
{
FILE * fp = fopen("sometext.txt");
int * A = malloc(100 * sizeof(int));
int * B = malloc(200 * sizeof(int));
/* Now I accidentally access A from 0-199 and B from 0-999 using a for loop*/
char buffer[500];
int i,x;
for (i=0; i<200; i++)
{
fgets(fp,buffer);
sccanf(buffer, "%d", x);
A[i]=x;
}
for (i=0; i<1000; i++)
{
fgets(fp,buffer);
sccanf(buffer, "%d", x);
B[i]=x;
}
}
Both for loop should not work. However, I somehow get passed the first loop and only get seg fault in the second loop. And the error I get is traced back to sccanf (I tested the code without assign any value to A or B, and it works. So the sccanf statement should be fine.) The gdb error message is : isoc99_sscanf (s=, format=).
The full bt message is below, SOL[] is my B[] here and the actual sscanf read more variables. I can post full code if you are interested.
#0 0x00007ffff7a6869b in _IO_vfscanf_internal (s=s#entry=0x7fffffffd3b0,
format=format#entry=0x4010f8 "%*d%5c%5c%5d %lf %lf %lf %*f %*f %*f\n",
argptr=argptr#entry=0x7fffffffd4d8, errp=errp#entry=0x0) at vfscanf.c:343
#1 0x00007ffff7a72a0c in __GI___isoc99_vsscanf (
string=0x7fffffffd650 " 4545SOL HW123234 2.687 0.089 7.120 -1.1448 0.0920 0.6016\n", format=0x4010f8 "%*d%5c%5c%5d %lf %lf %lf %*f %*f %*f\n",
args=args#entry=0x7fffffffd4d8) at isoc99_vsscanf.c:43
#2 0x00007ffff7a72997 in __isoc99_sscanf (s=<optimized out>,
format=<optimized out>) at isoc99_sscanf.c:31
#3 0x0000000000400a9c in read (PMI=0x603490, COION=0x606ce0,
COUNTERION=0x60dd70, SOL=0x7ffff7f58010, in=0x603010, out=0x603250)
at thick_calc.c:97
#4 0x0000000000400915 in main () at thick_calc.c:52
Thanks!
You are not reassiging the pointer, it should be
void main()
{
int * array;
allocation(&array);
if (array != NULL)
deallocation(array);
}
void allocation(int **result)
{
if (result == NULL)
return;
*result = malloc(8293 * sizeof(int));
}
void deallocation(int * result)
{
free(result);
}
by passing the pointer, you can modify it's content, but you cannot change where it points to, so you must pass a pointer to the pointer, i.e. the address to the pointer so you can modify where it points to.
The problem in your code is that your pointer remains invalid in the scope of main, so when you pass it to free it's not actually pointing to the malloced memory block.
Doing that is causes undefined behavior. Reading or writing past the malloced block causes undefined behavior, so you cannot expect a given behavior, because it's undefined.
It means, it could cause a Segmentation Fault, or it could work, or anything could happen because it's undefined.
Eventualy you will write to a special location in memory and something will happen, you can't be sure what is happening meanwhile since again it's undefined behavior.