I read tons of tutos and snippets, but I still don't understand why I get a segfault with this:
int fun(char **p) {
int i;
*p = malloc(2);
*p[0]=10;
*p[1]=20; // segfault NULL pointer
printf("fun()/n");
for (i=0; i<2; i++)
printf("%d ",*p[i]);
}
int main(int argc, const char *argv[])
{
char* buffer;
int i;
fun(&buffer);
printf("main()\n");
for (i=0; i<2; i++)
printf("%d ",buffer[i]);
return 0;
}
In gdb, it gives:
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000
0x0000000100000dea in fun (p=0x7fff5fbffab0) at test.c:10
10 *p[1]=20;
(gdb) p *p[0]
$1 = 10 '\n'
(gdb) p *p[1]
Cannot access memory at address 0x0
(gdb)
I have seen a lot of similar snippets, but there is surely something I am deeply misunderstanding.
You mean (*p)[1]. What you said is *(p[1]).
try returning the address of the same data type of the variable at the LHS.
malloc() by default returns a void value.
p = (char) malloc(2);
this way compiler knows how many bytes it has to move the pointer to fetch new variable.
Related
I have a method called printNums, where I would like to print integers from 1 - 10. For my assignment, I'm supposed to malloc an int pointer, set it, pass in to my function as a void* point and inside the function, cast it, deference it and print that integer out before each iteration of the counter.
However, I keep getting a segmentation fault after *((int*)ptr) and I'm not too sure why. Any help would be appreciated.
Here is my code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void* printNums(void *ptr);
int main(int argc, char **argv)
{
int *ptr = (int*)malloc(sizeof(int));
ptr = 0;
printNums(ptr);
return 0;
}
void* printNums(void *ptr){
int i = 0;
for (i = 0; i <= 10; i++){
*((int*)ptr) = i;
printf("%d\n", *((int*)ptr));
}
}
You're assigning ptr pointer to zero.
change ptr = 0; to *ptr = 0;.
You are resetting the address to zero:
ptr = 0;
Which means you will definitely (in most environments and operating systems) get a segmentation fault if you try to access it.
I think you wanted to set the value pointed by ptr to 0 before you can use, so by mistake you made ptr = 0
to make all the values pointed by ptr to be 0 you need to use memset
memset(ptr,0,sizeof(int));
However, I keep getting a segmentation fault after *((int*)ptr) and
I'm not too sure why.
You can try to find out yourself. Programming requires some debugging skills - forums are not the replacement.
void* printNums(void *ptr){
int i = 0;
for (i = 0; i <= 10; i++){
printf("%p\n", ptr);
//*((int*)ptr) = i;
//printf("%d\n", *((int*)ptr));
}
return ptr;
}
https://godbolt.org/z/EYhGKn
and the output
(nil)
(nil)
(nil)
(nil)
(nil)
(nil)
(nil)
(nil)
(nil)
(nil)
(nil)
And the answer is obvious: you dereference NULL pointer.
Now you can try to find out why you pass the NULL pointer to the function. As the program is 12 lines long it will not take too much time to discover the line:
ptr = 0;
Which assigns integer zero to the pointer. So the pointer is now NULL.
I've been staring at this problem for a while and I can't seem to find an obvious solution nor the vocabulary to describe the specific issue. I'll try my best:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
char** findWords(char** words, int wordsSize, int* returnSize) {
*returnSize = 15; //<- wordsSize and returnSize have the same memory address????
printf("wordsSize is %d\n", wordsSize);
for(int i=0; i<wordsSize; i++)
{
printf("i: %d first word: %s, len: %d\n", i, words[i], strlen(words[i]));
}
}
int main(void){
char **test; // this should be const char but func decl is predefined
test[0] = "Hello";
test[1] = "Alaska";
test[2] = "Dad";
test[3] = "Peace";
int *foo;
findWords(test, 4, foo);
printf("%d", *foo);
}
When findWords() gets called, I see that &wordsSize and *returnSize are the same (i.e. they have the same memory address)
[New Thread 3492.0x9d0]
Breakpoint 1, findWords (words=0x7efde000, wordsSize=4, returnSize=0x28ff24) at keyboardrow.c:15
15 printf("wordsSize is %d\n", wordsSize);
(gdb) print &wordsSize
$1 = (int *) 0x28ff24
(gdb) print returnSize
$2 = (int *) 0x28ff24
(gdb)
Am I missing something obvious? It seems to me that &wordsSize and returnSize should have different memory addresses since they are two separate variables.
char **test; // this should be const char but func decl is predefined
test[0] = "Hello";
test[1] = "Alaska";
test[2] = "Dad";
test[3] = "Peace";
You can't do what you are doing above. test doesn't point to any "meaningful" place.
The problem is
test[0] = "Hello";
test[1] = "Alaska";
test[2] = "Dad";
test[3] = "Peace";
all of these invoke undefined behavior, as test, on it's own does not point to a valid memory.
Before you can dereference test to obtain test[n], you need to make sure that test is pointed to a valid memory which is having enough size to make the test[n] access a valid one.
Instead of the above snippet, you can simple write
char * test[] = { "Hello", "Alaska", "Dad", "Peace" };
and get done with it.
Since you are invoking undefined behavior by calling a pointer that doesn't point to anywhere, various variables/ pointers may point to same memory address, just like in situations where different variables may contain the same garbage value!
I have a function to update an unsigned char* and cannot find where my bug is. I'm not sure if I need to allocate memory, or if I am pointing to the wrong memory space somewhere. I tried to follow a similar structure as posted here, but have not had success with an unsigned char.
My code so far:
#include <stdio.h>
void changeArray(unsigned char **arr)
{
unsigned char ptr[3] = {100, 101, 102};
*arr = ptr;
printf("%d\n", **(arr+0)); // This prints out the correct value of 100
}
int main(int argc, const char* argv[])
{
int i = 0;
unsigned char *blah;
unsigned char ptr2[3] = {103, 104, 105};
blah = ptr2;
printf("Blah is: \n");
for (i = 0; i < 3; i++) {
printf("%d,",*(blah+i)); //This prints out 103,104,105
}
changeArray(&blah);
printf("Blah is now: \n");
for (i = 0; i < 3; i++) {
printf("%d,", *(blah +i)); //This prints out 0,0,0
}
return 0;
}
Any help in determining how to properly access the values set in the changeArray() function would be greatly appreciated.
With this *arr = ptr; you are storing a pointer to a variable with automatic storage duration. The behaviour undefined.
You can dynamically allocate and return a pointer that way:
void changeArray(unsigned char **arr)
{
unsigned char ptr[3] = {100, 101, 102};
unsigned char *p = malloc(sizeof ptr);
memcpy(p, ptr, sizeof ptr);
*arr = p;
printf("%d\n", **(arr+0)); // This prints out the correct value of 100
}
You should also do error checking if malloc failed and remember to free the allocated memory after use in main.
The problem here is, ptr is local to changeArray() function. So once the function finishes execution, there is no existance of ptr. Hence, once you assign ptr to *arr
*arr = ptr;
and changeArray() execution gets over, accessing blah in main() now will invoke undefined behaviour.
FWIW, you don't need to pass the address of blah, you don't need a pointer-to-pointer at all. blah is already a pointer, which you can pass to changeArray() to alter the contents of the memory area it points to. You can do something like
void changeArray(unsigned char *arr)
{
for (int i = 0; i < 3; i ++)
arr[i] = 100+i;
}
and call it like
changeArray(blah);
I apologize by advance if my question seems absolutely trivial, but I don't understand why if I run
int main(){
int *count = 0;
printf("%d",*count);
}
I have no input (using Xcode) and an error:
Thread 1 : EXC_BAD_ACCESS(code=1, address = 0x0)
Could someone explain to me what this is?
What happens is dereferencing a null pointer, which is undefined behavior: your count is a pointer, which means that it needs to point to a valid location before you can read from it:
int main(){
int *count = malloc(sizeof(int)); // Give your pointer a valid location
*count = 123; // This is valid now
printf("%d", *count); // prints 123
free(count); // Don't forget to free allocated memory
}
You have declared count as a pointer to an integer value not as an integer value and you have initialized the pointer to be NULL (memory address 0).
You would want to do the following...
int main()
{
int buffer = 0;
int* count = &buffer;
printf( "var %d = %d\n", buffer, *count );
}
I have a small piece of code. I compiled it with -lmcheck as I am trying to debug a code where I have the same similar error.
I get this error when I run this code:
memory clobbered before allocated block
Can someone explain the reason why free(ptr) will throw me this error?
How else can I free the pointer?
Thanks.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define LEN 5
int main(int argc, char *argv[]){
char *ptr = NULL;
ptr = (char *) malloc(LEN+1);// +1 for string
strcpy(ptr, "hello");
int i = 0;
for(i = 0; i<LEN; i++)
{
printf("ptr[%d] = %c\n", i, ptr[i]);
ptr++;
}
free(ptr);
return 0;
}
You are incrementing ptr, therefore changing the address that it points to. You can't do that.
In your case, have a separate pointer, let's say char * p = ptr and do your operations with p leaving ptr intact so you can free(ptr) later.
EDIT Taking a second look at your code, I found that you are doing ptr++ when you shouldn't. You are accessing the characters in the array like ptr[i], if you mess with the ptr pointer, you are changing the base address and accessing the characters with ptr[i] can lead (and will lead) to unexpected results.
If you simply remove that line (ptr++) your code will magically work.
If you want to explore the pointer concept and try another solution, your code could look something like this:
int main(int argc, char *argv[]){
char *ptr = NULL;
char * p;
ptr = (char *) malloc(LEN+1);// +1 for string (please check for NULL)
p = ptr;
strcpy(ptr, "hello");
int i = 0;
while (*p) // note how I changed it to a while loop, C strings are NULL terminated, so this will break once we get to the end of the string. What we gain is that this will work for ANY string size.
{
printf("ptr[%d] = %c\n", i++, *p); // here i dereference the pointer, accessing its individual char
p++;
}
free(ptr);
return 0;
}
Because ptr no longer points to the base of the memory you allocated.
Also, after you increment ptr, the expression ptr[i] does not return what you might expect; and that is why the output starts with "hlo".
Find the answer in comments.
When you allocate some memory, typically, the memory management framework keep tracks of it by adding some more info (you can say Header and Footer) to the allocated memory area. When you free this memory, the same info is matched so as to detect any unwanted/invalid memory access.
int main(int argc, char *argv[]){
char *ptr = NULL;
char* temp = NULL; // Have a temp pointer.
ptr = (char *) malloc(LEN+1);// +1 for string
strcpy(ptr, "hello");
temp = ptr; // manipulate temp pointer instead of ptr itself
int i = 0;
for(i = 0; i<LEN; i++)
{
printf("ptr[%d] = %c\n", i, temp[i]);
temp++; // Why you are incrementing this? Just to print, there is no need of this.
}
free(ptr);
return 0;
}