I am getting segmentation fault in the following code
static char * result;
char s[31];
int i;
random_string(s, 10);
// for (i = 0; i < 15; i++){
// result[i] = s[i];
// }
strcpy(result, s);
printf("el result es %s\n", result);
where the function random_string is:
void random_string(char * string, int length)
{
/* Seed number for rand() */
int i;
for (i = 0; i < length -1; ++i){
string[i] = rand() % 90 + 65;
}
string[length] = '\0';
}
For some reason I am getting segmentation fault when using strcpy. Also copying byte by byte is not working. What is the problem? I am out of ideas.
The problem is that result has not been initialized. It results in undefined behavior. Before it can be used like that, you need to make sure it points to a valid buffer. For example:
result = malloc( strlen( s ) + 1 );
static char * result; is just an address without any allocated memory!
Try this:
[EDITED]
char * result = (char*)malloc(strlen(s) + 1);
You forgot to allocate memory to "result" pointer. Try next:
result = malloc( strlen( s ) + 1 );
strcpy(result, s);
result is just a uninitialised pointer.
You must assign result to a character buffer before using strcpy.
You need to assign a valid memory region to your result pointer using malloc or using static memory, as you are doing with your s string. Otherwise your pointer has just a random location assigned and your program receives a segfault by accessing it as it lies out of the boundaries of your program.
Declare result as a char array like
static char result[10];
or assign some memory to result pointer.
Related
I'm studying C at uni and am trying to access the string (the string representation of a binary-number) that was passed into a function to convert it into the integer-representation of that string.
Eg. "011" should return 3.
The string is the first 3 bits in a bitstream that's inputted in reverse.
char * temp_holder = (char *)malloc(sizeof(char) * 4);
int index_of_holder = 0;
for(int i = 2; i >= 0; i--){
printf("%c", buffer[i]);
temp_holder[index_of_holder] = buffer[i];
}
printf("\n");
int decimalValue = fromBinaryToInt(&temp_holder, 3);
printf("DECIMAL_VALUE: %d\n", decimalValue);
The fromBinaryToInt function is:
int fromBinaryToInt(char *string[], int length){
for(int i = 0; i < length; i++){
printf("%c", *string[i]);
}
int int_rep = strtol(*string, (char **)NULL, 2);
printf("REP: %d\n", int_rep);
return int_rep;
}
The subsequent error I get is:
==21==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffda9f47a08 at pc 0x000000500cdf bp 0x7ffda9f47980 sp 0x7ffda9f47978
- READ of size 8 at 0x7ffda9f47a08 thread T0
I thought this could be due to the null-terminating character so I played around with modifying the length variable (+/- 1) in the for-loop within fromBinaryToInt but that hasn't changed anything.
I also considered the for-loop only accessing the first element and nothing more - but my understanding is I've sent through the memory address and the length of the block so the for-loop should have access to the indexes.
Any help would be greatly appreciated,
Cheers :)
In this code:
int index_of_holder = 0;
for(int i = 2; i >= 0; i--){
printf("%c", buffer[i]);
temp_holder[index_of_holder] = buffer[i];
}
index_of_holder is never changed, so all the characters are put in temp_holder[0]. The rest of temp_holder remains uninitialized.
This:
int fromBinaryToInt(char *string[], int length)
declares string to be an array of pointers to char. It is indeed passed &temp_holder, which may be considered to be a pointer to the first element of an array of one pointer to char. However, a more normal usage is to declare a simple pointer to char
int fromBinaryToInt(char *string, int length)
and pass it temp_holder, as in fromBinaryToInt(temp_holder, 3).
As it is, where it is used here:
printf("%c", *string[i]);
This takes element i of the array. When i is 0 in the loop, that is fine, it takes the first element, which exists and is a pointer to char, and then deferences it with * and prints that. However, when i is 1, it attempts to take the second element of the array. That element does not exist, and the resulting behavior is undefined.
If the parameter were merely char *string, then this printf could be:
printf("%c", string[i]);
and, in calling strtol, you would simply pass string rather than *string:
int int_rep = strtol(string, (char **)NULL, 2);
Firstly, bug in below line, index_of_holder remains same all the time, please increment it.
temp_holder[index_of_holder] = buffer[i];
Secondly, in fromBinaryToInt() string is single pointer only so you can't do *string[i]); in the next printf statement.
Here is the working code
int fromBinaryToInt(char *string, int length){
for(int i = 0; i < length; i++){
printf("%c", string[i] ); /*since string is single pointer now you can do like before you did */
}
int int_rep = strtol(string, (char **)NULL, 2);
printf("REP: %d\n", int_rep);
return int_rep;
}
int main() {
char * temp_holder = (char *)malloc(sizeof(char) * 4);
char buffer[4] ="011";
int index_of_holder = 0;
for(int i = 2; i >= 0; i--){
printf("%c", buffer[i]);
temp_holder[index_of_holder] = buffer[i];
index_of_holder++;
}
printf("\n");
int decimalValue = fromBinaryToInt(temp_holder, 3);/* no need to pass address of temp_holder */
printf("DECIMAL_VALUE: %d\n", decimalValue);
return 0;
}
Need some help please. I have the following code.
char *lines[100];
int i;
for (i = 0; i < 100; i++)
{
char temp[10];
_itoa_s(i, temp,10);
char result[10] = "test";
strcat_s(result, temp);
lines[i] = (char*)malloc(sizeof(char));
lines[i] = result;
}
for (i = 0; i < 100; i++)
{
cout << lines[i] << endl;
}
Why does it print :
test99
test99
test99
...
It turns out that char result[10] will point to the
same memory location. Why ? Was expecting something like this :
test1
test2
test3
...
The first line here is a basically NOOP (actually it is creating a memory leak because you throw away the pointer returned by malloc by overwriting it on the next line).
lines[i] = (char*)malloc(sizeof(char)); // this is a basically a NOOP
lines[i] = result;
It's more or less like writing:
foo = 5;
foo = result;
So your code ends up like this:
for (i = 0; i < 100; i++)
{
char temp[10];
_itoa_s(i, temp,10);
char result[10] = "test";
strcat_s(result, temp);
lines[i] = result; // copying just the pointer,
}
So all lines[i] contain the pointer to the same memory location result.
Also the scope of result is limited to the part between {}, so once the for loop is terminated, result is likely to be overwritten at the next occasion.
You need this:
char *lines[100];
for (int i = 0; i < 100; i++)
{
char temp[10];
_itoa_s(i, temp,10);
char result[10] = "test";
strcat_s(result, temp);
lines[i] = (char*)malloc(sizeof(char) * strlen(result) + 1);
// ^string length ^space for NUL terminator
strcpy(lines[i], result); // actually copying the the string (not only the pointer)
}
You also need to free the allocated memory once you're done with it:
for (i = 0; i < 100; i++)
{
free(lines[i]);
}
In your code, due to
lines[i] = result;
all the pointers end up pointing to the same result, the last one.
You may want to use strcpy() if you're interested in the content.
But wait, there's another problem. You're written
lines[i] = (char*)malloc(sizeof(char));
which allocates 1 byte of memory, which is here, good for nothing. Before you use the pointer as destination in strcpy(), you need to make sure that the pointer points to sufficient memory, including the terminating null, to hold the concatenated string.
Advice: The devil is in the details. perform a careful study of the language before performing trial and error.
Here's my function.
char * substring(int begin, int end, char * string)
{
int size = end - begin + 1;
char * s = (char *)malloc (sizeof(size));
int i;
for (i = 0; i < size; i++)
{
s[i] = string[begin++];
}
return s;
}
So let's say my string was only supposed to be "I". But when I try to print out the string later, I get I + 3 extra characters that were unintended. How do I fix this?
First, change the line
char * s = (char *)malloc (sizeof(size));
to
char * s = malloc( size + 1 ); // + 1 for null terminator
sizeof (size) gives you the number of bytes in an integer (2 to 4 to 8 depending on your platform), which is not necessarily what you want.
Next, use the strncpy function to copy the first size characters of string:
strncpy( s, string, size );
Make sure the string is null-terminated:
s[size] = '\0';
You have extra characters printed since you haven't null-terminated the s string:
s[i] = 0;
return s;
Fix the allocation to size, and also note that the following may depend on your interpretation of begin and end, but if you interpret the end as pointing to the last character you intend to copy (this would be a-typical), then you will need to adjust the size by 1.
This is undefined behavior waiting to happen. Your biggest problem is that your allocation should be
char * s = (char *)malloc (size);
I m trying to free the memory space for an array of char:
static void cleanArray(char* array)
{
int i;
int size = strlen(array) + 1;
for(i = 0; i < size; i++)
free(array[i]);
free(array);
}
int main(){
char* array = (char *)malloc(1 * sizeof(char*));
int c;
for(c=0;c<100;c++){ //code to populate some string values in the array.
void *p = realloc(array, (strlen(array)+strlen(message)+1)*sizeof(char*));
array = p;
strcat(array, "some string");
}
cleanArray(array); //I get error only when I call this method.
}
But for the above code I m getting Segmentation fault error.
And when I just try the following code instead of cleanArray() I dont think the array is freed up:
free(array);
printf("%s",array); //it prints all the values in the array. Hence, I concluded it is not freedup.
Line free(array[i]); in loop have problem. array[i] is a char value(which is actually int by integer promotion) and passing that value to free will be considered as pointer. Now you are trying to free that address about which you do not have any idea.
There are multiple problems:
You don't need to call free() on each character of the string. Just call free(array).
sizeof(char*) in malloc() and realloc() is incorrect.
I have char * lines[1000] string that can hold 1000 characters. How to create 100 arrays of that string. I get error with this code down.
char * lines[1000];
lines = (lines*)malloc(100 * sizeof(lines));
main.c:19:20: error: expected expression before ')' token
The simplest way is:
char lines[100][1000];
Alternatively:
char* lines[100];
int i;
for (i = 0; i < 100; i++) {
lines[i] = malloc(1000);
}
...
for (i = 0; i < 100; i++) {
free(lines[i]);
}
The latter is a bit more flexible in that -- with minor modifications -- it permits you to allocate a different amount of memory for every string.
It looks like you want an array strings, each string holding at most 1000 characters. There are some issues with your code.
You've declared an array of char *s but what you really want is a pointer to an array of chars. For that, your declaration should be
char (*lines)[1000];
On the other hand, you shouldn't forget about the NULL bytes at the end of strings, and should probably instead declare
char (*lines)[1001];
To set the pointer, you'll want to use
lines = (char (*)[1001]) malloc(100 * sizeof(char[1001]));
or
lines = (char (*)[1001]) malloc(100 * sizeof(*lines));
the latter working because, with lines a pointer to an array of chars, *lines is a char[1001]. Remember to make sure you didn't get a NULL pointer back.
At the end, you should free the memory you've malloced with
free(lines);
You can write a for-loop as:
char * lines[1000];
int i = 0;
for (i = 0; i < 1000; i++)
{
lines[i] = (char*)malloc(100 * sizeof(lines));
}
Don't forget to free-up the memory pointed by all the pointers
for (i = 0; i < 1000; i++)
{
free(lines[i])
}
Why don't you create a 2 dimensional array?