"initializer element is not constant char" error in C - c

Here is my code:
#include <stdio.h>
#include<stdlib.h>
char *s = (char *)malloc (40);
int main(void)
{
s="this is a string";
printf("%s",s);
}
I am getting the following error:
error: initializer element is not constant char *s = (char *)malloc
(40);

You don't need to allocate memory in this way if you wanna initialize it in code, I mean:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *s = "this is a string"; // char s[] = "this is a string";
printf("%s",s);
return 0;
}
is just enough in this case. If you really want to assign const char string to your char array, this topic should enlighten you: Dynamically allocating memory for const char string using malloc()

You cannot not do that.
You can do this instead -
#include <stdio.h>
#include<stdlib.h>
#include <string.h>
char *s; // probably should avoid using global variables
int main(void)
{
s=malloc(40);
strcpy(s,"this is a string");
printf("%s",s);
free(s);
}
Other than this inside main you can do this -
char *s="this is a string"; //string literal you can't modify it
Or
char s[]="this is a string"; // modifiable string

You assign a pointer to a string constant to a variable, s, which is not declared to point to a constant. This is what you want:
#include <stdio.h>
int main(void)
{
const char *s = "this is a string";
printf("%s\n", s);
return 0;
}
In C there are basically three ways to declare "string" variables.
String constant pointers
If you need a name for a string that will not change, you can declare and initialize it like
const char *s = "a string";
Character arrays
If you need a string variable and you know in advance how long it needs to be you can declare and initialize it like
char s[] = "a string";
or like
char s[9];
strcpy(s, "a string");
Character sequence pointers
If you don't know in advance how large the array needs to be, you can allocate space during program execution:
char *s;
s = malloc(strlen(someString) + 1);
if (s != NULL) {
strcpy(s, someString);
}
The "+1" is to make room for the null character (\0).

Related

Change pointer of pointer in C

I'm trying to write a void function that gets a pointer to a pointer of a string (char**) as a parameter, and changes the original char* so it pointed to another string, lets say "hello".
Below is the code I've written:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void change_ptr(char **str_ptr)
{
char hello[] = "hello";
char *hello_ptr = hello;
*str_ptr = hello_ptr;
}
int main()
{
char str[] = "yay";
char *str_ptr = str;
char **ptr_to_str_ptr = &str_ptr;
change_ptr(ptr_to_str_ptr);
printf("%s\n", str);
return 0;
}
As you can see, Im getting the pointer to the pointer of the char* "yay", delivering it to the function, and in the function I'm getting the pointer to "hello", and changes *str_ptr (which is the pointer to the original string) to the pointer to hello. But when I print str at the end, it prints "yay".
What am I doing wrong?
(when I debug with printing the addresses, everything seems fine.)
This works:
#include <stdio.h>
void change_ptr(const char ** str_ptr)
{
*str_ptr = "hello";
}
int main()
{
char str[] = "yay";
const char * str_ptr = str;
const char ** ptr_to_str_ptr = &str_ptr;
change_ptr(ptr_to_str_ptr);
printf("%s\n", str_ptr);
}
Note that the string "hello" in this example is read-only because it is a string literal. I added const in a few places so you are reminded of this and the compiler will warn you if you try to write to the string. The pointer str_ptr can be modified, but not the string itself.

passing string to a pointer in c

I am fairly new in C. I want to assign string in a function to a pointer but I have no idea why it is not working?
This is the initial code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
void test(char* result) {
*result = "HELLO";
}
int main() {
char result[64];
test(result);
printf("%s", *result);
}
This is the error: warning: assignment makes integer from pointer without a cast. Since * result should store value and result is the address, shouldn't this work out?
Hello and welcome to C.
Your statement:
*result = "HELLO";
is the same as attempting to do the following:
result[0] = "HELLO"
which is attempting to set a single character to a string, and you can't do that.
you will need to copy the string character by character
luckily there is a function for that which you have included already with <string.h> called strcpy
strcpy(result,"HELLO")
This will work as long as your string to copy is fewer than 63 characters as you have defined in your main() function.
char result[64];
you should probably also send the length of the string to the test function and use strncpy
strncpy(result,"HELLO",length); // safe copy
and then terminate the string with '\0'
result[length-1] = 0;
your printf doesn't need to dereference the string pointer. So simply printf("%s",result); is fine.
so in summary:
void test(char* result,uint32_t len) {
strncpy(result,"HELLO",len); // safe copy (however "HELLO" will work for 64 length string fine)
result[len-1] = 0; // terminate the string
}
#define MY_STRING_LENGTH 64
int main() {
char result[MY_STRING_LENGTH ];
test(result,MY_STRING_LENGTH);
printf("%s",result); // remove *
}
You declared an array in main
char result[64];
Passed to the function it is converted to rvalue of the type char * that points to the first element of the array. The function deals with a copy of this pointer. Changing this copy of the pointer fors not influence on the original array.
Within the function the expression *result has the type char. So this assignment
*result = "HELLO";
does not make a sense.
In this call
printf("%s", *result);
there is again used an incorrect expression of the type char *result.
What you need is to use standard string function strcpy.
For example
#include <stdio.h>
#include <string.h>
void test(char* result) {
strcpy( result, "HELLO" );
}
int main( void ) {
char result[64];
test(result);
puts( result );
}
Problem:
When you store a character in a char varible,it puts the ASCII of the character in the memory.
char c='a';is the same aschar c=97;
You can verify this by using the code:
char c='a';
printf("%d",c);
So here is one way:
void test(char* result) {
*result++ = 'H';
*result++ = 'E';
*result++ = 'L';
*result++ = 'L';
*result = 'O';
}
int main() {
char result[64];
test(result);
printf("%s", result);
}
But it is redundant because there is a function called strcpy in <string.h>.
#include <stdio.h>
#include <string.h>
void test(char* result) {
strcpy( resul, "HELLO" );
}
int main() {
char result[64];
test(result);
puts( result );
}
Remove the '*' of the variable "result" after you've declared it and use the function "strcpy()" in your code.

thread 1 exc_bad_access (code=1 address=0x0)

I'm working on a project where I have to replace some char in a string.
I do not understand one of the errors I see.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void replaceLetters(char *text, char original, char new_char);
{
for (int counter = 0; text[counter] != '\0'; counter++)
{
if (text[counter] == original)//Error occurs here
{
text[counter] = new_char;
}
printf("%c", chr[counter]);
}
return 0;
}
int main()
{
char *text = "HallO";
char original = 'O';
char new_char = 'N';
replaceLetters(text, original, new_char);
return 0;
}
At the if statement the following error occurs: thread 1 exc_bad_access (code=1 address=0x0).
What does this mean, and how can I address it?
In c, string literals like "HallO" are stored in global read-only memory. If you want to modify the string, you will need to keep it in a buffer on the stack.
char text[6] = "HallO";
"What does this mean, and how can I address it?"
It is an access violation. The string you have defined
char *text = "HallO";
is referred to in C as a string literal, and is created in an area of read-only memory, resulting in an access violation.
This can be easily addressed by creating the original variable such that it is editable. eg:
char text[6] = "HallO"; //okay
char text[] = "HallO"; //better, let the compiler do the computation
char text[100] = "HallO"; //useful if you know changes to string will require more room

Why is this usage of memset() segfaulting?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char *str = "This is a string!";
int therealthing = sizeof(str[0]) * 4;
memset(str, 'b', therealthing);
printf("%s\n", str);
return 0;
}
This code causes a segfault, any ideas why?
I have already tried passing it as a memory address and as a pointer.
This is a string literal. It's immutable. Can't be changed.
char *str = "This is a string!";
You're trying to change it with memset. You could use an array of characters
char str[] = "This is a string!";
or
char * str = malloc(sizeof(char) * (strlen("This is a string!") + 1));
strcpy(str, "This is a string!");
You can't modify a string literal. It will invoke undefined behavior.
Try this instead
char str[] = "This is a string!";

Why char value copy won't work in OS X?

It's a textbook C code
void strcpy_new(char *s, char *t) {
while ((*s = *t) != '\0') {
s++;
t++;
}
}
int main(int argc, const char * argv[])
{
char *s = "this is line a";
char *t = "this is line b";
printf("%s", s);
strcpy_new(s, t);
printf("%s", s);
return 0;
}
when I run it with Xcode, I got EXEC_BAD_ACCESS.
The reason you get EXEC_BAD_ACCESS is because those string literals "this is line a" and "this is line b" are stored in read-only memory. Attempting to write to it (*s = *t) is undefined behavior and you are receiving a crash because of it.
To remedy this code you should allocate some memory for s so that it is large enough to hold the second string (t):
char s[] = "this is line a"; // contrived example, s and t are the same length
char *t = "this is line b";
strcpy_new(s, t);
I'm willing to bet that you're trying to run strcpy_new with a destination char *s that is a string literal
#include <string.h>
int main(int argc, char *argv[])
{
char *a = "Some String";
char *b = "Another string";
strcpy(b, a);
return 0;
}
will give an EXEC_BAD_ACCESS. The following, however, won't
#include <string.h>
int main(int argc, char *argv[])
{
char *a = "Some String";
char b[] = "Another string";
strcpy(b, a);
return 0;
}
The difference is that in the first case, b points to a block of memory in the __TEXT,__cstring,cstring_literals section of the executable, which is write protected. In the second case, it points to a block of memory on the stack.
The problem is that the effect of overwriting a string literal is undefined.
char *s = "this is line a";
char *t = "this is line b";
strcpy_new(s, t);
s and t are both off in the data section of the code, and your particular setup happens to give you an EXEC_BAD_ACCESS when you try changing them.
String literal are read-only. A good answer is found here: http://ubuntuforums.org/showthread.php?t=357869
String literals in C are read-only. In your sample code, "My string" is a string literal.
The str[] declaration copies the literal into writable memory (stack or heap). Therefore, your program can modify the string.
The * declaration initializes a pointer to the literal itself, so you have a pointer to a read-only segment. If you try to overwrite it, you get the SEGV.

Resources