Cuda 2D memory allocation and copy problem - c

int **F;
int **dev_pF;
size_t *pitchF;
void init_cuda_mem(int mF,int mT,int nF,int nT){
cudaMallocPitch((void **)dev_pF,pitchF,(nF + 2*nT -2)*sizeof(int),mF + 2*mT -2);
cudaMemcpy2D((void *)dev_pF,*pitchF,(void *)pF,*pitchF,(nF + 2*nT -2)*sizeof(int),mF + 2*mT -2,cudaMemcpyHostToDevice);
}
Well hello everyone
in the above snippet i am trying to allocate a 2D array using cudaMallocPitch
and then copying that array using cudaMemcpy2D from the host to the device
unfortunately it crashes and i think the error is (i think) at the cudaMemcpy2D
can someone help me locate it please

I think the issue is that you are mistaken with regards to pointers and pointers to pointers.
You should probably do something on the lines of:
int *dev_pF;
size_t pitchF;
void init_cuda_mem(int mF,int mT,int nF,int nT) {
cudaMallocPitch((void **)&dev_pF, &pitchF,(nF + 2*nT -2)*sizeof(int),mF + 2*mT -2);
cudaMemcpy2D((void *)dev_pF,pitchF,(void *)pF, pitchF,(nF + 2*nT -2)*sizeof(int),mF + 2*mT -2,cudaMemcpyHostToDevice);
}
Note the difference that you are now taking the address of the variables in the cudaMallocPitch call and then just using them directly in the second call.
In your original code, you were first asking cudaMalloc to store a pointer in whatever memory dec_pF happened to point to and store the size in whatever memory pitchF was pointing to. Both of these where unitialized, so disaster could occur there. In the second call you were converting dev_pF from a pointer to pointer to a regular pointer, so you are telling the memcpy to copy memory starting where the pointer was stored rather than where the allocated memory was stored. And since both the pointer to pointer and the size where unitialized at first, pretty much anything could happen.
Also, you are making use of a pF pointer that I cannot see in the original code, make sure it is initialized properly.

Related

do I need to allocate space for pointer as well as space for memory area whose address will be kept in pointer in pointer to pointer and realloc

I have this code
int main(int argc, char *argv[])
{
int i=1;
char **m=malloc(sizeof(char *)*i);
printf("%zu\n",sizeof *m);
m[0]=malloc(strlen("hello")+1);
strcpy(m[0],"hello");
printf("%s\n", m[0]);
i=2;
m=(char **)realloc(m,sizeof (char *)*i);
m[1]=malloc(strlen("hi")+1);
strcpy(m[1],"hi");
printf("%s %s \n",m[0],m[1] );
// TODO: write proper cleanup code just for good habits.
return 0;
}
this is how I am allocating pointer char **m 8 byte single char pointer
int i=1;
char **m=malloc(sizeof(char *)*i);
and this is how I am allocating area of space whose address will be kept in m[0]
m[0]=malloc(strlen("hello")+1);
strcpy(m[0],"hello");
printf("%s\n", m[0]);
I like to know is this normally how its done. I mean allocating space for pointer and then allocating space in memory that the pointer will hold.
Does m[0]=malloc(strlen("hello")+1); is same as this *(m+0)=malloc(strlen("hello")+1); and does this m[1]=malloc(strlen("hi")+1); this *(m+1)=malloc(strlen("hi")+1);
And I am increasing pointer to pointer numbers like this in allocation m=(char **)realloc(m,sizeof (char *)*i); before m[1]=malloc(strlen("hi")+1);
is there anything wrong with above code. I seen similar code on this Dynamic memory/realloc string array
can anyone please explain with this statement char **m=malloc(sizeof(char *)*i); I am allocating 8 byte single pointer of type char but with this statement m=(char **)realloc(m,sizeof (char *)*i); why I am not getting stack smaching detected error. How exactly realloc works. can anyone give me the link of realloc function or explain a bit on this please
I like to know is this normally how its done. I mean allocating space for pointer and then allocating space in memory that the pointer will hold.
It depends on what you are trying to achieve. If you wish to allocate an unspecified amount of strings with individual lengths, then your code is pretty much the correct way to do it.
If you wish to have a fixed amount of strings with individual lengths, you could just do char* arr [n]; and then only malloc each arr[i].
Or if you wish to have a fixed amount of strings with a fixed maximum length, you could use a 2D array of characters, char arr [x][y];, and no malloc at all.
Does m[0]=malloc(strlen("hello")+1); is same as this *(m+0)=malloc(strlen("hello")+1);
Yes, m[0] is 100% equivalent to *((m)+(0)). See Do pointers support "array style indexing"?
is there anything wrong with above code
Not really, except stylistic and performance issues. It could optionally be rewritten like this:
char** m = malloc(sizeof(*m) * i); // subjective style change
m[0]=malloc(sizeof("hello")); // compile-time calculation, better performance
why I am not getting stack smaching detected error
Why would you get that? The only thing stored on the stack here is the char** itself. The rest is stored on the heap.
How exactly realloc works. can anyone give me the link of realloc function or explain a bit on this please
It works pretty much as you've used it, though pedantically you should not store the result in the same pointer as the one passed, in case realloc fails and you wish to continue using the old data. That's a very minor remark though, since in case realloc fails, it either means that you made an unrealistic request for memory, or that the RAM on your system is toast and you will unlikely be able to continue execution anyway.
The canonical documentation for realloc would be the C standard C17 7.22.3.5:
#include <stdlib.h>
void *realloc(void *ptr, size_t size);
The realloc function deallocates the old object pointed to by ptr and returns a
pointer to a new object that has the size specified by size. The contents of the new
object shall be the same as that of the old object prior to deallocation, up to the lesser of
the new and old sizes. Any bytes in the new object beyond the size of the old object have
indeterminate values.
If ptr is a null pointer, the realloc function behaves like the malloc function for the
specified size. Otherwise, if ptr does not match a pointer earlier returned by a memory
management function, or if the space has been deallocated by a call to the free or
realloc function, the behavior is undefined. If memory for the new object cannot be
allocated, the old object is not deallocated and its value is unchanged.
Returns
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.
Notably there is no guarantee that the returned pointer always has the same value as the old pointer, so correct use would be:
char* tmp = realloc(arr, size);
if(tmp == NULL)
{
/* error handling */
}
arr = tmp;
(Where tmp has the same type as arr.)
Your code looks fine to me. Yes, if you are storing an array of strings, and you don't know how many strings will be in the array in advance, then it is perfectly fine to allocate space for an array of pointers with malloc. You also need to somehow get memory for the strings themselves, and it is perfectly fine for each string to be allocated with its own malloc call.
The line you wrote to use realloc is fine; it expands the memory area you've allocated for pointers so that it now has the capacity to hold 2 pointers, instead of just 1. When the realloc function does this, it might need to move the memory allocation to a different address, so that is why you have to overwrite m as you did. There is no stack smashing going on here. Also, please note that pointers are not 8 bytes on every platform; that's why it was wise of you to write sizeof(char *) instead of 8.
To find more documentation about realloc, you can look in the C++ standard, or the POSIX standard, but perhaps the most appropriate place for this question is the C standard, which documents realloc on page 314.

Is it possible to retrieve the start address from a pointer to allocated memory

It's known that you cannot in any standard way retrieve the allocated size of a memory block. For instance, if you do:
void *ptr = malloc(100);
There is no way to find out that it was 100 bytes allocated. But I started wondering if there is any way to do a similar thing, and that is retrieving the original pointer from a pointer pointing in that block. Like
void *ptr = malloc(100);
void *ptr2 = &ptr[10];
Can I in any way get ptr from ptr2 without knowing that it points at element 10?
I have not found a good use case for it, but something that is at least reasonable (and a little crazy) is if you want a function to allocate a string and return a pointer to the first digit in that string. I'm mostly just curious if it is possible.
Is it possible to retrieve the start address from a pointer to allocated memory
No. The details of allocation are an implementation detail, not specified by C. No portable way to find the size nor start from an arbitrary offsetted pointer alone.

malloc preventing garbage from being printed?

Program was programmed in C and compiled with GCC.
I was trying to help a friend who was trying to use trying to (shallow) copy a value that was passed into a function. His the value was a struct that held primitives and pointers (no arrays or buffers). Unsure of how malloc works, he used it similar to how the following was done:
void some_function(int rand_params, SOME_STRUCT_TYPEDEF *ptr){
SOME_STRUCT_TYPEDEF *cpy;
cpy = malloc(sizeof(SOME_STRUCT_TYPEDEF));// this line makes a difference?!?!?
cpy = ptr;// overwrites cpy anyway, right?
//prints a value in the struct documented to be a char*,
//sorry couldn't find the documentation right now
}
I told him that the malloc shouldn't affect the program, so told him to comment it out. To my surprise, the malloc caused a different output (with some intended strings) from the implementation with the malloc commented out (prints our garbage values). The pointer that's passed into the this function is from some other library function which I don't have documentation for at the moment. The best I can assume it that the pointer was for a value that was actually a buffer (that was on the stack). But I still don't see how the malloc can cause such a difference. Could someone explain how that malloc may cause a difference?
I would say that the evident lack of understanding of pointers is responsible for ptr actually pointing to memory that has not been correctly allocated (if at all), and you are experiencing undefined behaviour. The issue is elsewhere in the program, prior to the call to some_function.
As an aside, the correct way to allocate and copy the data is this:
SOME_STRUCT_TYPEDEF *cpy = malloc(sizeof(SOME_STRUCT_TYPEDEF));
if (cpy) {
*cpy = *ptr;
// Don't forget to clean up later
free(cpy);
}
However, unless the structure is giant, it's a bit silly to do it on the heap when you can do it on the stack like this:
SOME_STRUCT_TYPEDEF cpy = *ptr;
I can't see why there difference in the print.
can you show the print code?
anyway the malloc causes memory leak. you're not supposed to allocate memory for 'cpy' because pointer assignment is not shallow-copy, you simply make 'cpy' point to same memory 'ptr' point by storing the address of the start of that memory in 'cpy' (cpy is mostly a 32/64 bit value that store address, in case of malloc, it will store the address of the memory section you allocated)

Variables addresses in C

This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char *dd,aaa[500];
strcpy(aaa,"test 1");
dd=aaa;
printf("1. %s\n",dd);
strcpy(aaa,"test 2");
printf("2. %s\n",dd);
system("pause");
return 0;
}
When i have changed aaa variable by test 2 string, dd also changes, why?
It could be great if you said what you are trying to do in order for others to put your code into perspective.
Now you seem to have not understood well how pointers work. Since your code isn't really easy to read, the answer will be general.
Pointers 'hold' addresses to memory. If you have pointer ptr1 pointing towards memory block A and pointer ptr2 pointing towards ptr1, if you change ptr1, naturally ptr2 will experience the same changes. In your first block of code, you seem not to understand why someVar changes after otherVar changes. To make more explicit what #dmp has pointed out, you have told you program ( the operating system is managing memory for your program ) that someVar will point towards the value held in otherVar[0]. Now when otherVar[0] changes, someVar will change because that is how pointers are supposed to work, it is called to dereference a pointer - when you request the value of what the pointer points to - and you'll notice that things changed pr ptr2. So, please reread about pointers again.
In your second block of code, I don't know what you trying to accomplish but whatever it is, it will SEGFAULT. That is so because again, you haven't understood the relationship between pointers, arrays and how dynamic memory allocation works. For example, in the splittext function you have this line:
wchar_t *arr[2],*loc = wcsstr(stri, del), buf[DEFAULT_BUFLEN];
Right there: you telling the operating system to check the value at the 3rd cell of *arr while you haven't allocated memory for it. Also, when allocating memory, remember:
If you want to allocate memory for char to get a string your pointer will have to be a pointer towards char like this:
char* my_string = malloc( 256*sizeof(char))
Now you want to get memory allocated to pointers towards say variables of type FILE*.
If you write FILE** my_files = malloc( NUMBER_OF_FILES*sizeof(FILE)) it will get you into trouble. Rather write :
FILE** my_files = malloc( NUMBER_OF_FILES*sizeof(FILE*))
This is with regards to how you allocated memory for say arr.
Also don't cast the return value of malloc. It will hide many errors the compiler could have caught!
To sum up, first try to learn about pointers before moving on to a bit advanced uses of pointers, arrays and memory allocation; second you can't put incorrect code ( you will know it is incorrect either it doesn't compile or just crash ) and tell others : "hey look at that variable, that is where my problem is." Try to do more research into the question, try learning what tools can assist - a debugger in this case - and that will be improve the quality of your question. Third and last, if English is not your first language, you can mention it and others will be willing to assist in reformulating your question.
Hope you will do better next time!
UPDATE
After edit by OP, the question now is clearer and the OP's problem is about pointers.
dd's value changes because:
aaa is a pointer like this: char aaa[500] is equivalent to char* aaa = malloc(500*sizeof(char)). Now when you dd=aaa, you told the compiler that dd will point to the same memory address as does aaa. So every time you modify aaa dd gets modified because they point to the same thing in memory.
If that wasn't clear, try to reread the definition of a pointer.
What you ask is not clear, however, pointers in C are passed by value (there is a copy of the pointer pointing to the same location). If you dereference a pointer and change the value pointed to, the caller will see the change.
A quick pointer lesson should clear it up:
What happens on this line?
char *dd = aaa;
You've created a pointer to a character allocation called dd and pointed it to the memory address that aaa is stored at.
aaa's address is on the stack and static (you created it implicitly with your aaa[500]).
Now, when you put data into aaa, aaa's location in memory does not change, simply the data stored at that position in memory. When you try to print out the 'contents' of aaa, you're getting the characters stored at that point in memory. When you copy new data into aaa, the position in memory still remains the same, and thus dd is still pointing to the same memory space as aaa does.
My apologies if that's no clearer than anyone else's...

how to calculate size of pointer pointed memory?

In one function I have written:
char *ab;
ab=malloc(10);
Then in another function I want to know the size of memory pointed by the ab pointer.
Is there any way that I can know that ab is pointing to 10 chars of memory?
No, you don't have a standard way to do this. You have to pass the size of the pointed-to memory along with the pointer, it's a common solution.
I.e. instead of
void f(char* x)
{
//...
}
use
void f(char *x, size_t length)
{
//....
}
and in your code
char *ab = malloc( 10 );
f( ab, 10 );
It's a deep secret that only free() knows for sure. It's likely in your system, but in a totally implementation dependent manner.
A bit awkward, but if you want to keep everything together:
typedef struct
{ // size of data followed by data (C only trick! NOT for C++)
int dimension; // number of data elements
int data[1]; // variable number of data elements
} malloc_int_t;
malloc_int_t *ab;
int dimension = 10;
ab = malloc( sizeof(*ab) + (dimension-1)*sizeof(int) );
ab->dimension = dimension;
ab->data[n] // data access
I've changed the data type to int to make the code a more generic template.
You can't (portably anyway). You have to keep track of the size yourself.
Some implementations of malloc could give you an API to access that information, but there is no provisions in the standard for this.
The size is what you passed into malloc, you can use a global variable or macro to remember it.
There is no way, you have to store the size of the allocated memory in another variable.
No, unfortunately.
You need to pass the size of the block along with the pointer.
No.
Now, that being said, there are non-portable hacks to do this, but it is not safe to rely upon them.
If you know with 100% certainty that the memory was allocated via malloc(), you may be able to rewind the pointer a few bytes and inspect the 'malloc node' that is used to track which parts of memory have been allocated and which have not. However, I can not stress this enough--do not ever depend upon this.
There is no way to deduce the size of allocated memory from the pointer itself. Since ab is a char *, sizeof(ab) is the same as sizeof(char *), which obviously is not the same as the size of the allocated chunk of memory.
Since you called malloc with the required size, you know what the size is. Pass this number along with the pointer to the function that needs to know the size.
I had a structure and a char pointer pointing to its memory address. So relating it to your question, I wanted to find the size of the memory location it was pointing to i.e. the size of the structure. So logically what you do is, find the size of the object the pointer creates to. This worked for me:
unsigned char * buffer= Library1Structure;
int x=sizeof(Library1Structure);
So the value of x tells me the size of the memory location the pointer buffer points to.

Resources