please advise me on the following output:
int main()
{
char ***x = "jjhljlhjlhjl";
char ***q = "asddfwerwerw";
**q = **x;
printf("x:%s\n",x);
printf("q:%s\n",q);
}
Output: 1 Segmentation fault
This is what you should have:
#include <stdio.h>
int main(void) {
char *x = "jjhljlhjlhjl";
char *q = "asddfwerwerw";
q = x;
printf("x:%s\n",x);
printf("q:%s\n",q);
return 0;
}
If you want to initialize a character string, use char *x
Don't use ***x. That means pointer to pointer to pointer to a char.
Hope that helps.
"Segmentation fault" is not an output, it's an indication that your program has crashed.
This should come as no surprise, because string literals are char*, not char***. Trying to double-derefefence such pointers is undefined behavior, because it re-interprets the content of a string literal as a pointer to char. This is what is causing the crash.
You can modify your program as follows to make it legal:
int main() {
char *x = "jjhljlhjlhjl";
char tmp[] = "asddfwerwerw";
char *q = tmp;
*q = *x;
// This will produce an output that should be easy to explain:
printf("x:%s\n",x);
printf("q:%s\n",q);
}
Related
#include <stdio.h>
#include <string.h>
void replace (char a[]){
char *y;
*y = 'm';
char *p = a;
p = strchr(p, 'g');
while (p){
*p = *y;
p++;
p = strchr(p, 'g');
}
}
int main (){
char x[10];
gets(x);
replace(x);
puts(x);
return 0;
}
What's wrong with this replace function?
It doesn't output a string instead it says segmentation fault.
You're trying to write to a wild pointer here:
char *y;
*y = 'm';
y doesn't point anywhere in particular, so you get Undefined Behaviour (a seg fault in your particular case).
You are assigning value using an uninitialized pointer, y.
Why do you use pointer y anyway, instead of
*p = *y;
you can just say
*p = 'm';
y is not allocated. It is just a pointer and a pointer must point to a space in the memory. But you didn't allocate any space in the memory. So when you defferentiate it, is going to deferentiate the garbage address that a non itialized pointer has. Crash...
So rather than
char *y;
*y='p';
just write:
char y='p'; ///no pointer
Then a first improvment at the function. The function is too specific, just for a character, I would write like:
void replace (char a[],char from, char to)
{
char *p = a;
while(*p)
{
if(*p==from) *p=to;
p++;
}
}
If you compile your program with warnings enabled you should get a warning like this (with the GCC compiler):
warning: ‘y’ is used uninitialized in this function [-Wuninitialized]
*y = 'm';
^
Before you dereference the pointer y you need to know that it points to a valid object, but in your case y has not been assigned a value so it can point anywhere. Also you don't need any extra pointer; here is a more concise (and more general) version of the function:
static void replace(char old, char new, char s[])
{
s = strchr(s, old);
while (s != NULL) {
*s = new;
s = strchr(s, old);
}
}
Or without using strchr:
static void replace(char old, char new, char s[])
{
int i = 0;
while (s[i] != '\0') {
if (s[i] == old) {
s[i] = new;
}
i++;
}
}
I'm writing a function that reverses a cstring not in place but returns the reversed cstring. What exactly should the return type be?
#include <stdio.h>
#include <string.h>
const char* reverStr(const char *str)
{
char revStr[strlen(str)];
int i;
for(i = strlen(str)-1; i >= 0; i--)
revStr[strlen(str)-1-i] = str[i];
printf("returned value should be %s\n", revStr);
return revStr;
}
int main()
{
char aStr[] = "hello";
char aStr2[] = "goodbye";
printf("%s %s", aStr, aStr2);
char* tmp = reverStr(aStr);//tmp now has garbage
printf("\n%s", tmp);
printf(" %s", aStr);
return 0;
}
Gives
warning: function returns address of local variable [enabled by default]|
warning: initialization discards 'const' qualifier from pointer target type [enabled by default]|
I tried changing char* tmp to char tmp[] but it wouldn't compile. It confuses me when I should use an array and when I should use a pointer.
revStr is an array and ceases to exist after reverStr function exits. For more please read:
Where is the memory allocated when I create this array? (C)
const char* reverStr(const char *str)
{
char revStr[strlen(str)];
return revStr; /* Problem - revStr is a local variable trying to access this address from another function will be erroneous*/
}
const char* reverStr(const char *str)
{
const char * revStr = str;
return revStr; //ok
}
A modifiable l-value cannot have an array type. An l-value is an expression which can come on the left side of an assignment. You use an array when you want to declare lots of variables of the same type and you can index it easily since its layout will be in a sense contiguous.
You use pointers when you want to keep changing the values of the address where you variable points to.
You can do this:
char * p = "test";
p = "new";
But you cannot do this:
char p[] = "test";
char *p1 ="test1";
p = p1; //error
Because their (arrays and pointers) types are not the same and the array p is a non-modifiable l-value.
Here is your fixed code. I tried to make less modifications.
char revStr[strlen(str)]; allocates a local variable(an array) and when you are out of the scope of the reverStr function, its memory is released, which will lead any further usage of its pointer to be UB(segfault in most cases).
A correct way is to allocate the string on the heap and return its pointer like this
char* x = (char*)malloc(strlen(str));
...
return x;
This requires user to be responsible to free the memory. Or you could pass another parameter to your function for the result string.
I think you should use malloc to allocate a new string.
const char* reverStr(const char *str)
{
char *revStr;//using pointer
int i;
revStr = (char*)malloc(strlen(str));//dynamic allocation
for(i = strlen(str)-1; i >= 0; i--)
revStr[strlen(str)-1-i] = str[i];
printf("returned value should be %s\n", revStr);
return revStr;
}
An array is a pointer point to the head of continuous memory.
for example:
int a[] = {1,2,3};
The address in memory maybe:
--1000
|1|
--1004
|2|
--1008
|3|
--1012
1000, 1004, and 1012 are the value of address in memory.
Thus, the value of array a should be 1000.
printf("%d",a);// Yes, you can do it and you may get the value of 1000.
Also, you can use the following code.
int a[] = {1,2,3};
int *b;
b= a;
printf("%d",b[1]);// you will get "2".
You can consider that pointer is a set and array is in the set.
Therefore, you can NOT do this;
int a[] = {1,2,3};
int c = 0;
int *b = &c;
a = b;//error
Hi please kindly explain to me why is the code generating an error,
#include<stdio.h>
int main(){
char ***x;
char **q = *x;
char **(*c) = x;
char ***d = &q;
char ***p = "asdasd";
x=p;
printf("d:%s\n",d);
printf("q:%s\n",q);
printf("x:%s\n",x);
return 0;
}
Output:
1
Segmentation fault
Hi Thanks for the replys so if I init x, i still got an Segmentation fault on
printf("q:%s\n",q);
the output and code is shown below, please kindly advise why is d:1231 instead of 1231123124 and why x=p only change the value of x instead of all (x, q, d)
int main(){
char ***x = "1231123124";
char **q = *x;
char **(*c) = x;
char ***d = &q;
char ***p = "asdasd";
x=p;
printf("p:%s\n",p);
printf("d:%s\n",d);
// printf("q:%s\n",q);
printf("x:%s\n",x);
printf("c:%s\n",c);
return 0;
}
Output:
p:asdasd
d:1231
x:asdasd
c:1231123124
char **q = *x;
Here you are dereferencing an uninitialized pointer.
It's undefined behaviour, in this case it usually results a segfault (in practice your code will try to dereference some random memory location, or NULL if your compiler initializes local variables (this is typical for debug/non-optimized builds)).
These are type errors.
printf("d:%s\n",d); // d is char***, not char*
printf("q:%s\n",q); // q is char**, not char*
printf("x:%s\n",x); // x is char***, not char*
The %s specifier expects a char * argument, or possibly void *, const char *, etc., but never a char ** or char ***.
I need help figuring out why I am getting a segmentation fault here. I have gone over it and I think I am doing something wrong with the pointers, but I can figure out what.
My Program:
#include <stdlib.h>
#include <stdio.h>
void encrypt(char* c);
//characters are shifted by 175
int main(){
char* a;
*a = 'a';
/*SEGMENTATION FAULT HERE!*/
encrypt(a);
printf("test:%c/n",*a);
return 0;
};
void encrypt(char* c){
char* result;
int i=(int)(*c);
i+=175;
if(i>255)
{
i-=256;
}
*c=(char)i;
};
The problem is here:
char *a;
*a = 'a'
Since the variable "a" is not initialized, *a = 'a' is assigning to a random memory location.
You could do something like this:
char a[1];
a[0] = 'a';
encrypt(&a[0]);
Or even just use a single character in your case:
int main(){
char a = 'a';
encrypt(&a);
printf("test:%c/n",a);
return 0;
};
char* a;
*a = 'a';
/*SEGMENTATION FAULT HERE!*/
There isn't any "there" there. You've declared a and left it uninitialized. Then you tried to use it as an address. You need to make a point to something.
One example:
char buffer[512];
char *a = buffer;
(Note buffer has a maximum size and when it falls out of scope you cannot reference any pointers to it.)
Or dynamic memory:
char *a = malloc(/* Some size... */);
if (!a) { /* TODO: handle memory allocation failure */ }
// todo - do something with a.
free(a);
That pointer a does not get the actual space where to store the data. You just declare the pointer, but pointing to where? You can assign memory this way:
char *a = malloc(1);
Then it won't segfault. You have to free the variable afterwards:
free(a);
But in this case, even better,
char a = 'a';
encript(&a);
I have this short code:
#include <stdio.h>
void fastSwap (char **i, char **d)
{
char *t = *d;
*d = *i;
*i = t;
}
int main ()
{
char num1[] = "hello";
char num2[] = "class";
fastSwap ((char**)&num1,(char**)&num2);
printf ("%s\n",num1);
printf ("%s\n",num2);
return 0;
}
The output of this short program is:
claso
hells
and I just don't understand why the last letters of each char[] are swapped.
Any ideas?
fastSwap ((char**)&num1,(char**)&num2);
This is undefined behavior. You can't cast a pointer to array of char to a pointer to pointer to char. What you need is:
const char* num1 = "hello";
const char* num2 = "class";
fastSwap (&num1,&num2);
Also, you'll need to change the declaration of fastSwap and add inner-level const to arguments
void fastSwap (const char **i, const char **d)
I'm assuming you're trying to swap the contents of the num1 and num2 arrays by just manipulating pointers, so that after calling fastswap the contents of num1 will be "class" and num2 will be "hello".
If that's the case, then this won't work for a number of reasons. Arrays are not pointers, even though array expressions are often converted to pointer types. Secondly, you cannot modify the value of an array expression.
If you want to keep num1 and num2 as arrays (as opposed to pointers to string literals) and be able to swap their contents, you'll need to something more along these lines:
void fastswap(char *i, char *d)
{
while (*i && *d)
{
char t = *i;
*d++ = *i;
*i++ = t;
}
}
which will be called as
fastswap(num1, num2);
You are passing pointers to pointers to chars. You probably just want to pass pointers to chars like this:
#include <stdio.h>
void fastSwap (char *i, char *d)
{
char t = *d;
*d = *i;
*i = t;
}
int main ()
{
char num1[] = "hello";
char num2[] = "class";
fastSwap (num1,num2);
printf ("%s\n",num1);
printf ("%s\n",num2);
return 0;
}
This swaps the first character of the 2 char arrays.