I am writing a code and i hope this summon my problem.
Any help is appreciated>
I created an array by:
intermediateBinCounts = (int *)malloc(bin_count * thread_count * sizeof(int));
and want it to increment value in another function:
for(int i=privateStartingIndex; i<privateEndingIndex; i++){
int returnedBinIndex = findBin(data[i]);
int intermBinCountIndex = (threadIndex*bin_count)+returnedBinIndex;
intermediateBinCounts[intermBinCountIndex]++;
printf("\nthis is value %d\n", intermediateBinCounts[intermBinCountIndex]);
}
intermBinCountIndex is integer which is returned from the function and their value in my case are among 0, 1, 2, 3 only.
but my printf is returning:
this is value -1163005938
this is value -1163005937
this is value -1163005938
I don't know if my question is able to articulate my issue if it is not able to please let me know so that I could edit it again my best.
I want that intermediateBinCounts to be initialized to zero and increment the value at that index which value is returned from the function call i.e findBin.
I want that intermediateBinCounts to be initialized to zero
Well, you don't want that. intermediateBinCounts is a pointer and you want to set it to the value returned by malloc.
What you want to set to zero is the memory that intermediateBinCounts points to!
You can use a simple loop after the malloc- like:
int * intermediateBinCounts = malloc(bin_count * thread_count * sizeof(int));
for (int i=0; i < bin_count * thread_count; ++i)
{
intermediateBinCounts[i] = 0;
}
or use calloc instead of malloc as calloc zero initialize the allocated memory:
int* intermediateBinCounts = calloc(bin_count * thread_count, sizeof(int));
This declares a pointer to int, without already defining it, this is for headers
(though doing this implies global variables which many users recommend against):
extern int* pointer;
This defines that pointer, without initialising it; this is for exactly one code file:
int* pointer;
This defines and initialises the pointer; use it instead of above:
int* pointer=NULL;
This allocates some memory to the pointer:
pointer = malloc(sizeof(int));
This initialises the allocated memory:
*pointer=0;
This uses the initialised value pointed to by the pointer and increments it; doing this before above means undefined behaviour and would explain your unexpected values:
*pointer = *pointer +1;
Please check your code for what you are actually doing when.
Most likely you did not do the initialising.
Related
I want to allocate memory dynamically inside a function. The function is named func_1 and is declared as follows:
int func_1(int **destination);
Here destination is a pointer to a pointer. This pointer contains the address of the pointer to which I want to allocate memory dynamically inside the function.
The function func_1 has the following code:
void func_1(int **destination)
{
*destination = (int*)malloc(sizeof(int) * 10);
for(int i = 0 ; i < 10 ; i++)
{
*destination[i] = i; //segmentation fault comes HERE
}
}
Below is my main() function:
int main()
{
int *pointer;
func_1(&pointer);
return 0;
}
When I try to run this program, I get a segmentation fault (SIGSEGV) error. I used GDB to locate the source of this fault, and it turned out that the line inside the for loop is the culprit for this error.
Please note that I wish to retain the values I have assigned to the dynamically allocated memory inside the function, once the function exits, and that's the reason due to which I have passed the address of the pointer to which I want to allocate memory dynamically.
I want to know:
Why am I getting this error ?
How can this be fixed ?
Thanks for help !
[] (array subscripting) operator has precedence 2
* (dereference) operator has precedence 3
In your code *destination[i] means the same as *(destination[i]). This value is uninitialized and it leads to segmentation fault.
If you will use explicit priority of operation (*destination)[i] you will get the expected result.
void func_1(int **destination)
{
*destination = (int*)malloc(sizeof(int) * 10);
for(int i = 0 ; i < 10 ; i++)
{
(*destination)[i] = i; //no segmentation fault
}
}
you can read more about precedence here
Full code:
#include <stdio.h>
#include <stdlib.h>
void func_1(int **destination)
{
*destination = (int*)malloc(sizeof(int) * 10);
for(int i = 0 ; i < 10 ; i++)
{
(*destination)[i] = i;
}
}
int main()
{
int *pointer;
func_1(&pointer);
return 0;
}
Why am I getting this error ?
You are overwriting the destination pointer instead of assigning the value returned by malloc to the pointer pointed to by the destination pointer.
Instead of *destination = (int*)malloc(sizeof(int) * 10) you should type **destination = malloc(sizeof(int) * 10).
Instead of *destination[i] = i you should type (**destination)[i] = i.
In C, the array subscript operator [] has a higher precedence than the indirection operator *. In addition to that, the former is left-to-right associative, while the latter is right-to-left associative.
In your case this means that you need to type (**destination)[i] = i; instead of **destination[i] = i, because otherwise the [i] will be evaluated before the ** and you end up indirecting a wild pointer (which will cause a segmentation fault extremely likely in the general and absolutely certainly in this case, since you are referencing a null pointer when i == 0).
How can this be fixed ?
The "just make it work" fix is the one I presented above.
However, that does not address the fundamental issue with your code, which is that it is unnecessarily complicated. Using a pointer to a pointer is very error-prone and should be avoided. Indeed, there is no need to use one at all in this case.
The following does exactly what you want without all the unnecessary complexity:
int* func_1()
{
int* destination = malloc(sizeof(int) * 10);
for (int i = 0; i < 10; ++i)
{
destination[i] = i;
}
return destination;
}
int main()
{
int* pointer = func_1();
free(pointer);
return 0;
}
Please note that I wish to retain the values I have assigned to the dynamically allocated memory inside the function, once the function exits, and that's the reason due to which I have passed the address of the pointer to which I want to allocate memory dynamically.
As I demonstrated above, there is no reason to pass a pointer to the pointer to the function. Memory allocated with malloc is yours to use forever , you just need to keep track of it and release it with a call to free when you no longer need it. How you keep track of the memory doesn't matter - simply returning a pointer is enough in this case. Modifying pointer inside func_1 rather than catching the function's return value provides no additional benefit and only serves to make the code more complicated than it needs to be.
I get the impression that you are somewhat confused about pointers, so I recommend that you revise the subject. Here is a quite clear explanation regarding pointers that also covers pointers to pointeres (and pointers to pointers to pointers): How do pointers work in C?
Read more:
Operator Precedence and Associativity in C
What is a segmentation fault?
I have to dynamically increase a length of double array. I know, how to do it with char array, so I tried this:
int main() {
char * tmp = NULL;
for (int i = 1; i <= 4; i++) {
tmp = realloc(tmp, i * sizeof(char));
tmp[i] = 'i';
}
puts("char OK");
double * tmp1 = NULL;
for (int i = 1; i <= 4; i++) {
tmp1 = realloc(tmp1, i * sizeof(double));
tmp1[i] = 0;
}
return 0;
}
The first array works fine. But the second one crushes with message realloc(): invalid next size.
These are my 2 questions:
Why this way doesn't work in a double array?
How to dynamically increase the size of array of doubles?
UPD:
removed a typo
TL;DR: Both the snippets are wrong, the first one appears to work because of undefined behavior.
To elaborate, the problem is with your indexing logic. C uses a 0-based indexing. So, inside the loop which is staring the iteration from value of i as 1, by using
tmp[i] = .......
you're trying to access invalid memory, at this point, only access up to tmp[i-1] is valid.
You need to use tmp1[i-1] = 0;, and likewise.
That said,
Always check for the success of the memory allocator functions before using the returned pointers.
Never use the form
pointer = realloc (pointer, ......)
because, in case realloc call fails, you'll end up losing the original pointer, too.
Quoting C11, chapter ยง7.22.3.5
The realloc function returns a pointer to the new object (which may have the same
value as a pointer to the old object), or a null pointer if the new object could not be
allocated.
and
[....] If memory for the new object cannot be
allocated, the old object is not deallocated and its value is unchanged.
Always use a temporary pointer variable to store the return value of realloc(),
check for the success of the call [not-null return value] and
then assign it back to the original variable, if needed.
My problem is that i am not sure how to allocate memory properly. I have researched it but to no avail. Some help regarding malloc would be great.
int main(int argc, char *argv[]) {
int i, a[5000], c = 1, m, n, input;
scanf("%d", &input);
for (i = 0; i <= 9999; i += 2) {
a[c] = i;
c++;
}
for (n = 2; n < 1118; n++) {
for (m = a[n]; m < a[5000]; m++) {
a[m] = a[m+1];
}
}
printf("%d", a[input]);
free (*a);
return 0;
}
'a' is allocated on stack therefore no need to free it.
You only need to free variables allocated by *alloc family of functions.
First of all, C arrays have 0-based indexing. By setting the intial value of c to 1 and then using as index inside the loop, you're going off-by-one. This invokes undefined behavior.
After that, you don't need to do free (*a);, a is an array, not a pointer returned by a memory allocator functions, malloc() or family.
That said, in this code, *a does not give you a pointer, at all, it is same as a[0] which is of type int.
Finally, without any bound checking from user supplied value of input, using a[input] may very well be accessing out of bound memory, causing UB.
FWIW, passing a pointer to free() which is not returned previously by malloc() and family also invokes undefined behavior.
malloc takes one argument - the number of bytes to allocate. It returns a void pointer (which is a pointer to a section of memory that can hold any data type).
Here's an example.
int *array = malloc(sizeof(int) * 10);
This allocates a 10-element array of integers. Note it leaves your data uninitialized, so the contents of the array are undefined. There's a function called calloc that does initialize it to zeros.
Also, a style tip. You might try to cast the result of a malloc call to a pointer for the type of data you will store in it (for example, int *array = (int *)malloc(sizeof(int) * 10);. This is frowned upon by C programmers for reasons explained in this post.
The pointer to my global variable is turning to crud after freeing the local resource that I use to set the value in c.
this is the .c class
char* resource_directory;
void getResourcePath()
{
char *basePath = SDL_GetBasePath();
char* resource_dir = (char*)malloc(37 * sizeof(char));
for(int i = 0; i < 25; i++)
{
resource_dir[i] = basePath[i];
}
strcat(resource_dir, "resources/");
resource_dir[36] = '\0';
*resource_directory = *resource_dir;
free(basePath);
// free(resource_dir); <--- If I free here the value goes to crud
}
(this line below should say the value at resresource_directorydir equals the value at resource_dir) right?
*resource_directory = *resource_dir;
so the value at the address of the first pointer should get the value of the address at the 2nd but after trying to free the resource towards the end of the function.
even doing a print statement of the addresses show that they have different addresses.
SDL_Log("%d, %d", &resource_directory, &resource_dir);
example output : 245387384, 1361037488
I get the feeling that I am making a silly mistake here but I don't know what it is.
This line,
*resource_directory = *resource_dir;
is assigning the first value resource_dir points to, to the uninitialized pointer resource_directory, it's equivalent to
resource_directory[0] = resource_dir[0];
which is clearly not what you want.
You need to assign the pointer
resource_directory = resource_dir;
but you shouldn't use a global variable for that, and specially
Don't malloc() it, you have to free() everything you malloc() and global variables make it hard.
Don't use malloc() for fixed size objects, instead declare it as an array with the appropriate size, like this
char resource_directory[37];
Copy strings with strcpy() instead of writing a loop your self
for(int i = 0; i < 25; i++)
{
resource_dir[i] = basePath[i];
}
woule be
strcpy(resource_dir, basePath);
One thing you should notice when using a global variable like this is that if you call getResourcesPath() more than once, you are going to leak resources, if you must use global variables to carry values that need to live as long as the whole program lives, try to make their initialization static, and you can completely avoid using global variables for that, because everything that you declare and initialized in the stack frame of main() will hafe the same lifetime as the program, so you can pass it as parameters to any function that requires them from within main(), if you have many of these variables, create a struct to hold them, and pass the struct across the functions that need these resources, this is a very common technique in fact.
This statements
SDL_Log("%d, %d", &resource_directory, &resource_dir);
outputs as integer values the addresses of global variables resource_directory and local variable resource_dir. Of course their addresses are different.
As for this statement
*resource_directory = *resource_dir;
then it stores the first character of the string pointed to by resource_dir at the address that is stored in pointer resource_directory. However initially resource_directory was initialized by zero as an object with the static storage duration. So the program has undefined behaviour.
I think you mean the following
resource_directory = resource_dir;
That is you wanted that resource_directory would point to the string built in the function.
And there is no sense to use statement
free(resource_dir); <--- If I free here the value goes to crud
necause in this case statement
resource_directory = resource_dir;
also does not have sense.
If resource_directory need to point to the built in the function string then you shall not destroy it.
Take into account that using magic numbers 37 and 25 makes the program unclear and error-prone.
A pointer is a variable that contains a numeric value which happens to be the address of a memory location. For example, a NULL pointer is a variable containing the value 0. Assigning the notion of "isa pointer" to is a way of notifying the compiler of your intended use: that is, you cannot use pointer syntax on non-pointer variables. But until you do use pointer syntax, they more or less behave like normal variables.
int i = 0;
int* p = &i;
int j;
int* q;
j = i; // j has the same value as i
q = p; // q has the same value as p
At the end of the above code, p and q point to the same address. We only use the * syntax when we want to dereference a pointer:
q = p;
*q = *p; // copies the `int` pointed to by `p` to
// the `int` memory location pointed to by `q`,
// which is the same location.
Note that it is possible to nest pointers:
int** pp = &p;
p is int*, so &p is int**.
pp is a numeric value, it is the address of a memory location that contains an int*. *pp means fetch the value at the memory location contained in pp which will retrieve a second numeric value - the value that is in p, which is itself an int* and thus a second address. **pp will retrieve us the integer to which p points.
Your assignment
*resource_directory = *resource_dir;
copies the pointed-to-values, not the addresses.
Since you have tagged your question as C++ I'm going to conclude by offering this alternative implementation:
std::string resource_dir;
void getResourcePath()
{
char *basePath = SDL_GetBasePath();
resource_dir = base_path;
resource_dir += "resources/";
free(basePath);
}
If you need the c-string value of resource_dir subsequently, use resource_dir.c_str().
Alternatively, if you require a C implementation:
char* resource_dir;
void getResourcePath()
{
const char subPath[] = "resources/";
size_t length;
char *basePath = SDL_GetBasePath();
if (resource_dir)
free(resource_dir);
length = strlen(basePath) + sizeof(subPath);
resource_dir = (char*)malloc(length);
snprintf(resource_dir, length, "%s%s", basePath, subPath);
free(basePath);
}
I want to create an integer pointer p, allocate memory for a 10-element array, and then fill each element with the value of 5. Here's my code:
//Allocate memory for a 10-element integer array.
int array[10];
int *p = (int *)malloc( sizeof(array) );
//Fill each element with the value of 5.
int i = 0;
printf("Size of array: %d\n", sizeof(array));
while (i < sizeof(array)){
*p = 5;
printf("Current value of array: %p\n", *p);
*p += sizeof(int);
i += sizeof(int);
}
I've added some print statements around this code, but I'm not sure if it's actually filling each element with the value of 5.
So, is my code working correctly? Thanks for your time.
First:
*p += sizeof(int);
This takes the contents of what p points to and adds the size of an integer to it. That doesn't make much sense. What you probably want is just:
p++;
This makes p point to the next object.
But the problem is that p contains your only copy of the pointer to the first object. So if you change its value, you won't be able to access the memory anymore because you won't have a pointer to it. (So you should save a copy of the original value returned from malloc somewhere. If nothing else, you'll eventually need it to pass to free.)
while (i < sizeof(array)){
This doesn't make sense. You don't want to loop a number of times equal to the number of bytes the array occupies.
Lastly, you don't need the array for anything. Just remove it and use:
int *p = malloc(10 * sizeof(int));
For C, don't cast the return value of malloc. It's not needed and can mask other problems such as failing to include the correct headers. For the while loop, just keep track of the number of elements in a separate variable.
Here's a more idiomatic way of doing things:
/* Just allocate the array into your pointer */
int arraySize = 10;
int *p = malloc(sizeof(int) * arraySize);
printf("Size of array: %d\n", arraySize);
/* Use a for loop to iterate over the array */
int i;
for (i = 0; i < arraySize; ++i)
{
p[i] = 5;
printf("Value of index %d in the array: %d\n", i, p[i]);
}
Note that you need to keep track of your array size separately, either in a variable (as I have done) or a macro (#define statement) or just with the integer literal. Using the integer literal is error-prone, however, because if you need to change the array size later, you need to change more lines of code.
sizeof of an array returns the number of bytes the array occupies, in bytes.
int *p = (int *)malloc( sizeof(array) );
If you call malloc, you must #include <stdlib.h>. Also, the cast is unnecessary and can introduce dangerous bugs, especially when paired with the missing malloc definition.
If you increment a pointer by one, you reach the next element of the pointer's type. Therefore, you should write the bottom part as:
for (int i = 0;i < sizeof(array) / sizeof(array[0]);i++){
*p = 5;
p++;
}
*p += sizeof(int);
should be
p += 1;
since the pointer is of type int *
also the array size should be calculated like this:
sizeof (array) / sizeof (array[0]);
and indeed, the array is not needed for your code.
Nope it isn't. The following code will however. You should read up on pointer arithmetic. p + 1 is the next integer (this is one of the reasons why pointers have types). Also remember if you change the value of p it will no longer point to the beginning of your memory.
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define LEN 10
int main(void)
{
/* Allocate memory for a 10-element integer array. */
int array[LEN];
int i;
int *p;
int *tmp;
p = malloc(sizeof(array));
assert(p != NULL);
/* Fill each element with the value of 5. */
printf("Size of array: %d bytes\n", (int)sizeof(array));
for(i = 0, tmp = p; i < LEN; tmp++, i++) *tmp = 5;
for(i = 0, tmp = p; i < LEN; i++) printf("%d\n", tmp[i]);
free(p);
return EXIT_SUCCESS;
}
//Allocate memory for a 10-element integer array.
int array[10];
int *p = (int *)malloc( sizeof(array) );
At this point you have allocated twice as much memory -- space for ten integers in the array allocated on the stack, and space for ten integers allocated on the heap. In a "real" program that needed to allocate space for ten integers and stack allocation wasn't the right thing to do, the allocation would be done like this:
int *p = malloc(10 * sizeof(int));
Note that there is no need to cast the return value from malloc(3). I expect you forgot to include the <stdlib> header, which would have properly prototyped the function, and given you the correct output. (Without the prototype in the header, the C compiler assumes the function would return an int, and the cast makes it treat it as a pointer instead. The cast hasn't been necessary for twenty years.)
Furthermore, be vary wary of learning the habit sizeof(array). This will work in code where the array is allocated in the same block as the sizeof() keyword, but it will fail when used like this:
int foo(char bar[]) {
int length = sizeof(bar); /* BUG */
}
It'll look correct, but sizeof() will in fact see an char * instead of the full array. C's new Variable Length Array support is keen, but not to be mistaken with the arrays that know their size available in many other langauges.
//Fill each element with the value of 5.
int i = 0;
printf("Size of array: %d\n", sizeof(array));
while (i < sizeof(array)){
*p = 5;
*p += sizeof(int);
Aha! Someone else who has the same trouble with C pointers that I did! I presume you used to write mostly assembly code and had to increment your pointers yourself? :) The compiler knows the type of objects that p points to (int *p), so it'll properly move the pointer by the correct number of bytes if you just write p++. If you swap your code to using long or long long or float or double or long double or struct very_long_integers, the compiler will always do the right thing with p++.
i += sizeof(int);
}
While that's not wrong, it would certainly be more idiomatic to re-write the last loop a little:
for (i=0; i<array_length; i++)
p[i] = 5;
Of course, you'll have to store the array length into a variable or #define it, but it's easier to do this than rely on a sometimes-finicky calculation of the array length.
Update
After reading the other (excellent) answers, I realize I forgot to mention that since p is your only reference to the array, it'd be best to not update p without storing a copy of its value somewhere. My little 'idiomatic' rewrite side-steps the issue but doesn't point out why using subscription is more idiomatic than incrementing the pointer -- and this is one reason why the subscription is preferred. I also prefer the subscription because it is often far easier to reason about code where the base of an array doesn't change. (It Depends.)
//allocate an array of 10 elements on the stack
int array[10];
//allocate an array of 10 elements on the heap. p points at them
int *p = (int *)malloc( sizeof(array) );
// i equals 0
int i = 0;
//while i is less than 40
while (i < sizeof(array)){
//the first element of the dynamic array is five
*p = 5;
// the first element of the dynamic array is nine!
*p += sizeof(int);
// incrememnt i by 4
i += sizeof(int);
}
This sets the first element of the array to nine, 10 times. It looks like you want something more like:
//when you get something from malloc,
// make sure it's type is "____ * const" so
// you don't accidentally lose it
int * const p = (int *)malloc( 10*sizeof(int) );
for (int i=0; i<10; ++i)
p[i] = 5;
A ___ * const prevents you from changing p, so that it will always point to the data that was allocated. This means free(p); will always work. If you change p, you can't release the memory, and you get a memory leak.