dereferencing c-pointer in LabVIEW - pointers

My .DLL function outputs a C-pointer to a string which I need to dereference. I realized that I need to dereference the pointer twice, and I know there should be a built in function in LabVIEW which does just that. But I can't seem to find it.

In my experience, any memory that will exist in LabVIEW needs to be allocated in LabVIEW. So allocate a char buffer in LabVIEW and pass it in as a String and CStr Pointer in the Call Library Function.
Do everything you can in C and toss the results back out into Labview in a CStr.
WARNING: If you memcpy() outside the bounds of the allocated memory, Labview will most likely crash and you won't be able to catch the error. So either use try / catch with secure version of memcpy, over allocate in Labview, or test sizes.
C++:
void TestDLL(char Name[], int SizeOfLabviewMemory){
char *StringInC = "Hello World!";
int SmallerStringSize = 0;
if(strlen(StringInC) < SizeOfLabviewMemory){
SmallerStringSize = strlen(StringInC);
}else{
SmallerStringSize = SizeOfLabviewMemory;
}
memcpy(Name, StringInC, SizeOfLabviewMemory);
}

Related

Can I have boolean buffer in OpenCL and change its value during kernel execution, example to break while loop

I want to do some experiments in OpenCL and I want to know possibility to change states during kernel execution from host code using buffer.
I attempted to alter the state of a while loop in the kernel code by modifying the buffer value from within the host code, however the execution is hung.
void my_kernel(
__global bool *in,
__global int *out)
{
int i = get_global_id(0);
while(1) {
if(1 == *in) {
printf("while loop is finished");
break;
}
}
printf("out[0] = %d\n", out[0]);
}
I call second time the function clEnqueueWriteBuffer() to change state of input value.
input[0] = 1;
err = clEnqueueWriteBuffer(commands, input_buffer,
CL_TRUE, 0, sizeof(int), (void*)input,
0, NULL,NULL);
At least for OpenCL 1.x, this is not permitted, and any behaviour you may observe in one implementation cannot be relied upon.
See the NOTE in the OpenCL 1.2 specification, section 5.2.2, Reading, Writing and Copying Buffer Objects:
Calling clEnqueueWriteBuffer to update the latest bits in a region of the buffer object with the ptr argument value set to host_ptr + offset, where host_ptr is a pointer to the memory region specified when the buffer object being written is created with CL_MEM_USE_HOST_PTR, must meet the following requirements in order to avoid undefined behavior:
The host memory region given by (host_ptr + offset, cb) contains the latest bits when the enqueued write command begins execution.
The buffer object or memory objects created from this buffer object are not mapped.
The buffer object or memory objects created from this buffer object are not used by any command-queue until the write command has finished execution.
The final condition is not met by your code, therefore its behaviour is undefined.
I am not certain if the situation is different with OpenCL 2.x's Shared Virtual Memory (SVM) feature, as I have no practical experience using it, perhaps someone else can contribute an answer for that.

C functions returning an array

Sorry for the post. I have researched this but..... still no joy in getting this to work. There are two parts to the question too. Please ignore the code TWI Reg code as its application specific I need help on nuts and bolts C problem.
So... to reduce memory usage for a project I have started to write my own TWI (wire.h lib) for ATMEL328p. Its not been put into a lib yet as '1' I have no idea how to do that yet... will get to that later and '2'its a work in progress which keeps getting added to.
The problem I'm having is with reading multiple bytes.
Problem 1
I have a function that I need to return an Array
byte *i2cBuff1[16];
void setup () {
i2cBuff1 = i2cReadBytes(mpuAdd, 0x6F, 16);
}
/////////////////////READ BYTES////////////////////
byte* i2cReadBytes(byte i2cAdd, byte i2cReg, byte i2cNumBytes) {
static byte result[i2cNumBytes];
for (byte i = 0; i < i2cNumBytes; i ++) {
result[i] += i2cAdd + i2cReg;
}
return result;
}
What I understand :o ) is I have declared a Static byte array in the function which I point to as the return argument of the function.
The function call requests the return of a pointer value for a byte array which is supplied.
Well .... it doesn't work .... I have checked multiple sites and I think this should work. The error message I get is:
MPU6050_I2C_rev1:232: error: incompatible types in assignment of 'byte* {aka unsigned char*}' to 'byte* [16] {aka unsigned char* [16]}'
i2cBuff1 = i2cReadBytes(mpuAdd, 0x6F, 16);
Problem 2
Ok say IF the code sample above worked. I am trying to reduce the amount of memory that I use in my sketch. By using any memory in the function even though the memory (need) is released after the function call, the function must need to reserve an amount of 'space' in some way, for when the function is called. Ideally I would like to avoid the use of static variables within the function that are duplicated within the main program.
Does anyone know the trade off with repeated function call.... i.e looping a function call with a bit shift operator, as apposed to calling a function once to complete a process and return ... an Array? Or was this this the whole point that C does not really support Array return in the first place.
Hope this made sense, just want to get the best from the little I got.
BR
Danny
This line:
byte *i2cBuff1[16];
declares i2cBuff1 as an array of 16 byte* pointers. But i2cReadBytes doesn't return an array of pointers, it returns an array of bytes. The declaration should be:
byte *i2cBuff1;
Another problem is that a static array can't have a dynamic size. A variable-length array has to be an automatic array, so that its size can change each time the function is called. You should use dynamic allocation with malloc() (I used calloc() instead because it automatically zeroes the memory).
byte* i2cReadBytes(byte i2cAdd, byte i2cReg, byte i2cNumBytes) {
byte *result = calloc(i2cNumBytes, sizeof(byte));
for (byte i = 0; i < i2cNumBytes; i ++) {
result[i] += i2cAdd + i2cReg;
}
return result;
}

In CUDA, how to copy an array of device pointers to device memory?

For example, I allocate these following pointers:
float *data_1, *data_2, *data_3, *data_4;
//Use malloc to allocate memory and fill out some data to these pointers
......
//Filling complete
float *data_d1,*data_d2,*data_d3,*data_d4;
cudaMalloc((void **)&data_d1,size1);
cudaMalloc((void **)&data_d2,size2);
cudaMalloc((void **)&data_d3,size3);
cudaMalloc((void **)&data_d4,size4);
cudaMemcpy(data_d1,data_1,size1,cudaMemcpyHostToDevice);
cudaMemcpy(data_d2,data_2,size2,cudaMemcpyHostToDevice);
cudaMemcpy(data_d3,data_3,size3,cudaMemcpyHostToDevice);
cudaMemcpy(data_d4,data_4,size4,cudaMemcpyHostToDevice);
After this, I should already get 4 device pointers containing the exact data as host pointers do. Now I'd like to store these pointers into one array of pointers as following,
float *ptrs[4];
ptrs[0] = data_d1;
ptrs[1] = data_d2;
ptrs[2] = data_d3;
ptrs[3] = data_d4;
Now I'd like to transfer this array of pointers to CUDA kernel. However, I know that since ptrs[4] is actually on host memory, I need to allocate a new pointer on device. So I did this,
float **ptrs_d;
size_t size = 4 * sizeof(float*);
cudaMalloc((void ***)&ptrs_d,size);
cudaMemcpy(ptrs_d,ptrs,size,cudaMemcpyHostToDevice);
And then invoke the kernel:
kernel_test<<<dimGrid,dimBlock>>>(ptrs_d, ...);
//Declaration should be
//__global__ void kernel_test(float **ptrs_d, ...);
In the kernel_test, load data in the following syntax:
if (threadIdx.x < length_of_data_1d)
{
float element0 = (ptrs[0])[threadIdx.x];
}
Compiling is OKay, but when debugging, it gives an error of access violation.
Perhaps there're a lot of errors in my code. But I just want to figure out why I can't pass device pointers in this way and what is the proper way to access it if it is allowed in CUDA to pass array of device pointers to kernel function.
So how should I fix this issue? Any suggestions are appreciated. Thanks in advance.
One possibility is to allocate a void pointer, like CUDA expects as as standart, too. When passing it into your kernel, you can cast it to float**.
I did it in that way:
void* ptrs_d = 0;
cudaMalloc(&ptrs_d, 4*sizeof(float*));
cudaMemcpy(ptrs_d, ptrs, 4*sizeof(float*), cudaMemcpyHostToDevice);
kernel_test<<<dimGrid, dimBlock>>>((float**)ptrs_d);

C++ pointer is initialized to null by the compiler

So I've been stuck on a memory problem for days now.
I have a multi-threaded program running with c++. I initialize a double* pointer.
From what I've read and previous programming experience, a pointer gets initialized to garbage. It will be Null if you initialize it to 0 or if you allocate memory that's too much for the program. For me, my pointer initialization, without allocation, gives me a null pointer.
A parser function I wrote is suppose to return a pointer to the array of parsed information. When I call the function,
double* data;
data = Parser.ReadCoordinates(&storageFilename[0]);
Now the returned pointer to the array should be set to data. Then I try to print something out from the array. I get memory corruption errors. I've ran gdb and it gives me a memory corruption error:
*** glibc detected *** /home/user/kinect/openni/Platform/Linux/Bin/x64-Debug/Sample-NiHandTracker: free(): corrupted unsorted chunks: 0x0000000001387f90 ***
*** glibc detected *** /home/user/kinect/openni/Platform/Linux/Bin/x64-Debug/Sample-NiHandTracker: malloc(): memory corruption: 0x0000000001392670 ***
Can someone explain to me what is going on? I've tried initializing the pointer as a global but that doesn't work either. I've tried to allocate memory but I still get a memory corruption error. The parser works. I've tested it out with a simple program. So I don't understand why it won't work in my other program. What am I doing wrong? I can also provide more info if needed.
Parser code
double* csvParser::ReadCoordinates(char* filename){
int x; //counter
int size=0; //
char* data;
int i = 0; //counter
FILE *fp=fopen(filename, "r");
if (fp == NULL){
perror ("Error opening file");
}
while (( x = fgetc(fp)) != EOF ) { //Returns the character currently pointed by the internal file position indicator
size++; //Number of characters in the csv file
}
rewind(fp); //Sets the position indicator to the beginning of the file
printf("size is %d.\n", size); //print
data = new char[23]; //Each line is 23 bytes (characters) long
size = (size/23) * 2; //number of x, y coordinates
coord = new double[size]; //allocate memory for an array of coordinates, need to be freed somewhere
num_coord = size; //num_coord is public
//fgets (data, size, fp);
//printf("data is %c.\n", *data);
for(x=0; x<size; x++){
fgets (data, size, fp);
coord[i] = atof(&data[0]); //convert string to double
coord[i+1] = atof(&data[11]); //convert string to double
i = i+2;
}
delete[] data;
fclose (fp);
return coord;
}
Corrupt memory occurs when you write outside the bound of an array or vector.
It's called heap underrun and overrun (depends on which side it's on).
The heap's allocation data gets corrupted, so the symptom you see is an exception in free() or new() calls.
You usually don't get an access violation because the memory is allocated and it belongs to you, but it's used by the heap's logic.
Find the place where you might be writing outside the bounds of an array.

Where's the memory leak?

So I'm learning pointers and having a difficult time identifying the memory leak here. I confess I have never used malloc() before and am new to pointer arithmetic. Thanks in advance.
/*filename: p3.c */
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *buffer;
char *p;
int n;
/* allocate 10 bytes */
buffer = (char *) malloc(10);
p = buffer;
for (n=0; n<=10; n++)
*p++ = '*';
p = buffer;
for (n=0; n <=10; n++)
printf("%c ", *p++);
return 0;
}
The rule is rather simple, for every malloc there must be a free. If you have more mallocs than frees you forgot to de-allocate memory and so you have a memory leak. If you have more frees than mallocs you're trying to de-allocate memory that has already been de-allocated and that's not something you want.
You simply need to free your buffer by using the free() function, when you don't need the buffer anymore:
/* ... */
free( buffer );
return 0;
}
Simply remember to balance each call to malloc with a call to free, when the memory is not used anymore.
The operations on your p variable won't affect buffer. They are two pointers pointing to the same area (at start), but they're still two distinct variables. So incrementing p won't increment buffer.
So nothing wrong with the pointer operations on p, except the fact you are writing out of bounds, as stated by Daniel Fisher in the comments of your question.
Also note that you should also always check for NULL, after the malloc call, as malloc may fail. It's pretty rare nowadays, but if it fails, your program will probably crash, as you will then dereference a NULL pointer:
buffer = malloc( 10 );
if( buffer == NULL )
{
/* Error management - Do not use buffer */
}
The cast to char * is not needed on malloc, unless you are dealing with C++. In C, it's valid to assign a void pointer to another pointer type.
It is not n<=10 you want, but n<10.
You call malloc and never call free. Of course it leaks.
In principle, every single allocation you request from the alloc family of function should be freeed as soon as you are done with them.
Buffers that you continue to use to up to the termination of the program are formally leaks, but not a problem as long as you are allocating a well defined number of them. That includes what you are doing here.

Resources