Deferencing a pointer to a pointer causes a segmentation fault - c

Why is that the fourth line has an error?
char** h_addr_list = "Hello world";
char* s = "Hello world";
printf("%s\n", s);
printf("%s\n", *h_addr_list); // segmentation fault

Because when %s qualifier is given, printf function expects a pointer to NULL terminated character-string to be passed as the argument.
The h_addr_list itself is a pointer to NULL terminated character string.
The *h_addr_list is not.
So, these would work,
printf("%s\n", h_addr_list);
printf("%c\n", *h_addr_list);

Related

C char pointer get a specific character

probably a dumb question but how do you access a specific character in a char pointer?
I've tried following...
char *pointer = "Hello";
printf("%s", pointer); // prints "Hello"
printf("%s", &pointer[0]); // also prints "Hello"
But what I want is printf(???) => "H". A single character. Or the "e". How is that possible?
pointer is a pointer to char, also called a char *.
After char *pointer = "Hello";, pointer points to the “H”.
When printf is given %s, it takes a char * and prints all the characters it finds starting at that location, until a null character is seen.
To tell printf to print a single character, pass it the actual character value (not a pointer) and use %c:
printf("%c", *pointer);
or:
printf("%c", pointer[0]);
or, for the “e” instead of the “H”:
printf("%c", pointer[1]);
char* pointer = "Hello";
Creates a pointer and assigns it to the base address of "Hello".
pointer and &pointer[0] are the same thing.
pointer[n] takes the address of "Hello" and offsets it by the number 'n', be sure not to index of the end of the address or you will read rubbish.
So:
pointer[0] = 'H'
pointer[1] = 'e'
pointer[2] = 'l'
pointer[3] = 'l'
pointer[4] = 'o'
pointer[5] = 0
You want to access the char of char* simply use [] operator, just like arrays.
char *pointer = "Hello";
printf("%s", pointer); // ok
printf("%s", &pointer[0]); // wrong way of accessing specific element (it is same as the base address.., thus %s prints the whole thing)
Instead you're accessing the address of the first element of char* or string literal.. why!
printf("%c", pointer[0]); // use this one
Just like arrays, access the required element.
However, to get it better, notice here:
#include <stdio.h>
int main() {
char *pointer = "Hello";
printf("%s\n\n", pointer); // ok
printf("%c", pointer[0]);
printf("%p == %p\n", (void *)&pointer[0],(void *)pointer);
// cast to void * to avoid undefined behavior
// pointed out by #ex nihilo
printf("%p", pointer+1);
return 0;
}
Output:
Hello
H0x55da21577004 == 0x55da21577004
0x55da21577005
as you can see, the pointer holds the address of the first element which is: &pointer[0] thus you get the same output.

Initialize and print const char pointer

I got this code:
const char *newLine = "\n";
printf('Content: %c\n', *newLine);
What happens now is a memory error.
Why is that happening?
The code crashes with a memory error (segmentation fault) because printf expects a null-terminated string as the first argument (i.e. a valid address pointing to some characters ending in a zero byte), but you are passing an (effectively random) integer to it which is not a valid address (unless you are very, very lucky :-).
As people commented, use double quotes to pass an actual string allocated by the compiler somewhere:
const char *newLine = "\n";
printf("Content: %c\n", *newLine);
Try this code
const char* newLine = "new Line";
printf("Content: %s\n", newLine);

Copy c-string char by char to dynamic char*

I have a const char* string, I want to copy that string character by character to dynamic `char*.
const char *constStr = "Hello world";
char *str = (char*) malloc(strlen(constStr)+1);
while(*constStr){
*str = *constStr;
constStr++;
str++;
}
printf("%s", str);
free(str);
The problem is that previous code just copies each character of constStr to only the first index of the str. I don't know why?
As others have pointed out, you are incrementing str pointer in each iteration, so you always end up printing the end of the string.
You can instead iterate over each character without incrementing the pointer. The following code worked for me:
const char *constStr = "Hello world";
int len = strlen(constStr);
char *str = (char *) malloc(len + 1);
int i;
for (i = 0; i <= len; ++i) {
str[i] = constStr[i];
}
printf("%s", str);
free(str);
Yes you didn't null terminate the string. That was the primary problem. To be more clear, it is not that you didn't nul terminate the string which is the problem but rather your use of them where a pointer to a nul terminated char array is expected is the problem. But even if you did there was significant amount of problems in the code.
You allocated the memory and the casted the return value of malloc which is unnecessary. void* to char* conversion is implicitly done.
malloc might not be able to service the request, it might return a null pointer. It is important to
check for this to prevent later attempts to dereference the null pointer.
Then you started copying - you copied everything except the NUL terminating character. And then you passed it to printf's %s format specifier which expects a pointer to a null terminated char array. This is undefined behavior.
The one position, in the str is uninitialized - beware that accessing uninitialized value may lead to undefined behavior.
Also there is another problem, From standard §7.22.3.3
The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.
Yes so is is the case here? No. when you called free(str) str is not pointing to the dynamically allocated memory returned by the malloc. This is again undefined behavior.
The solution always is to keep a pointer which stores the address of the allocated chunk. The other answers already showed them (without repeating them - both of them provides a good solution).
You can use strdup or strcpy also - even if you don't need them now - get accustomed with them. It helps to know those. And yes strdup is not part of standard, it is a POSIX standard thing.
Example:
const char *constStr = "Hello world";
char *str = malloc(strlen(constStr)+1);
if( !str ){
perror("malloc");
exit(EXIT_FAILURE);
}
char *sstr = str;
while(*constStr){
*str = *constStr;
constStr++;
str++;
}
*str = 0;
printf("%s", sstr);
free(sstr);
Here's the "classical" string copy solution:
const char *constStr = "Hello world";
char *str = malloc(strlen(constStr) + 1), *p = str;
/* Do not forget to check if str!=NULL !*/
while((*p++ = *constStr++));
puts(str);
The problem is that previous code just copies each character of
constStr to only the first index of the str. I don't know why?
Use index variable.
Don't forget terminating '\0' because you have a good chance of segmentation fault.

How to Print Pointers in c?

Can someone please explain to me why this code gives a Segmentation Fault:
char string[] = "this is a string";
char * string2 = "this is another string";
printf("%s\n",string );
printf("%s\n", string2);
printf("string[2]= %s, string2 = %s\n", string[2], &string2 );
It also gives the same error when I try to print
*string2 or *string2[2] or &string2[2]
I am really confused about this, likewise examples I see on websites seem to print but not this one.
The first two are fine but in the last one you probably want:
printf("string[2]= %c, string2 = %p\n", string[2], (void *)&string2 );
^ ^
You are getting a segmentation fault because you are tricking printf into interpreting a small integer (string[2]) as a pointer (that's what %s expects).
char * string2 = "this is another string";
declaration causes string2 point to t (first character of string) and that doesn't mean *string2 is entire string (On derefrencing string2),i.e, "this is another string". If you will try to print *string2 with %s, it will cause segmentation fault but with %c it will print t.
To print a pointer use %p specifier.

C: Segmentation Fault while using printf

This one is probably very simple, but I can't seem to get it working.
I have this very simple snippet of code:
#include <stdio.h>
#include <string.h>
int main(void)
{
char buf[100];
char *p = buf;
strcpy(p, "Test string");
printf("%s\n", *p);
}
Which causes a segmentation fault when I run it. GDB outputs:
Program received signal SIGSEGV, Segmentation fault.
0xb76af3b3 in strlen () from /lib/i686/cmov/libc.so.6
But I still don't get it.
Comments would be appreciated, thanks.
When you write
printf("%s\n", *p);
the *p will be the value at p[0] which is a character. The printf however is looking for an array of chars, thus causing it to segfault. Remember that in C, strings are just arrays of characters, and arrays are effectively pointers to the first element, this is why you don't need to dereference.
To fix this remove the * to get:
printf("%s\n", p);
You're passing a character to printf; you should be passing the pointer.
char buf[100];
char *p = buf;
strcpy(p, "Test string");
printf("%s\n", p); // p, not *p
Use this:
printf("%s\n", p);
use "p" instead of "*p"
Replace
printf("%s\n", *p);
with
printf("%s\n", p);
When you use %s, printf expects you to pass a char*. You are passing a char instead.
just pass the string(the pointer):
printf("%s\n", p);
If you want to print the first char, then:
printf("%c\n", *p);
%s causes printf() to dereference *p. Suppose the string was "Test string".
Then on my Solaris sparc box: (in a test program) p would be "aimed at" the address 0x54657374. The probability of that particular address being part of your process space is next to zero.
That is what caused the SIGSEGV signal (segfault).

Resources