initializing array pointer to a struct - c

I get the Error run-time check failure #3, and i have to initialize P and i know why but not how to do it.
Points is supposed to be a variable 2D array like float* points[3] for testing purposes its constant for now.
CVAPI(CvPOSITObject*) lvCreatePOSITObject( float points[5][3], int point_count )
{
CvPoint3D32f* P; //array of structs with int x,y,z
for(int i = 0; i< point_count; i++)
{
P[i].x = points[i][0];
P[i].y = points[i][1];
P[i].z = points[i][2];
}
return cvCreatePOSITObject(P,point_count);
}

I don't know much about OpenCV, but I think you should allocate some memory to store the data.
#include <stdlib.h> // add this to the head of the file to use malloc
CVAPI(CvPOSITObject*) lvCreatePOSITObject( float points[5][3], int point_count )
{
CvPoint3D32f* P; //array of structs with int x,y,z
P = malloc(sizeof(CvPoint3D32f) * point_count); // allocate some memory
for(int i = 0; i< point_count; i++)
{
P[i].x = points[i][0];
P[i].y = points[i][1];
P[i].z = points[i][2];
}
return cvCreatePOSITObject(P,point_count);
}
This code may be bad because this may not free the allocated buffer.

Related

How to use Malloc pointers in comparison to array in C

I created a struct called PLAYER and I want to create an list that stores the pointers to the PLAYER object.
If I want to accomplish it with
PLAYER **ptr = malloc(10*sizeof(PLAYER *));
How can I assign the pointers to each index? I tried:
PLAYER *a;
PLAYER *b;
ptr[0] = a;
ptr[1] = b;
1.This seems to work. Can I get some explanation on the memory address behind it?
I also tried:
ptr = a;
//increase the address and assign b
ptr += sizeof(PLAYER *);
ptr = b;
2.This does not work correctly I think. Can I see a correct way of assign the list without using the [] brackets?
3.If I allocate only one entry's size and assign multiple ones:
PLAYER **ptr = malloc(1*sizeof(PLAYER *));
ptr[0] = a;
ptr[1] = b;
I can get these PLAYER object by using ptr[0] ptr[1], but will this cause any problems like overwrite other memories?
4.If I use [] brackets, do I need to malloc at each index in order to use it?
PLAYER *ptr[10];
for(int i = 0; i < 10; i++)
ptr[i] = malloc(sizeof(PLAYER *));
5.Do I need to free an array after using it? such as:
char ptr[10] = "abc";
//do something with ptr
free(ptr);
char *ptr2[10] = {"123", "abc"};
free(ptr2);
Any help would be much appreciated!
If you have a PLAYER **ptr = malloc(10*sizeof(PLAYER *));
That means you have to malloc for every ptr[i] = malloc(sizeof(PLAYER));
Accessing the array at indexes would be ptr[i]->somevalue
NOTE: if you have pointers inside the struct you need to allocate for those as well!!
Freeing your memory would be:
for(int i = 0; i<10;i++){
free(ptr[i]->anyAllocatedPointersInside);
free(ptr[i]);
}
free(ptr);
SPECIFICALLY IN THAT ORDER
If you update the post with the full struct I can update mine to more accurately help you.
When in doubt, think of malloc() allocations in these terms: it allocates raw memory, and it doesn't know anything about your structs!
When you think in these terms, you'll get it right.
Let's try to answer to your questions:
You are basically instancing within the stack a pointer, with any content into it, just as int hello;. That integer can contain anything, because you don't set it as in int hello = 2;. The same thing is happening with your pointers: int * hello; will be a pointer (to an integer) that can contain any address. Hence, if you dereference a pointer like that, your chances to get caught into SIGSEGV are not low.
Then, once you have created those pointers that can be anything, you're assigning their address to the pointer of pointers array you've allocated. Don't do that.
That doesn't work correctly, because if you have an array of pointers to a given type, you can simply increment with += n, the compiler will calculate the appropriate "sizeof(type_you're-pointing_to)" and will add that automatically. This is the main purpose of declaring a pointer to a given type.
You're effectively overwriting other memory.
Brackets are just pointer dereferencing: *ptr+n same as ptr[n].
You need to free each line, and then the array of pointers of pointers.
Basically every pointer you get with malloc(), you have to free it with free(). DO NOT call free() to any other pointers that hasn't been spit out from malloc().
Let me show you some code I have just written to show you better:
#include <stdlib.h>
#include <stdio.h>
#include <string.h> // for memset
#define N_POINTERS 4
#define M_PLAYERS_PER_LINE 3
struct PLAYER
{
int id;
int score;
int age;
};
int
main()
{
// Allocate the array of pointers, big enough to old N pointers.
struct PLAYER ** pointers = malloc(N_POINTERS*sizeof(struct PLAYER*));
// Always better zeroize pointers arrays.
memset(pointers, 0, N_POINTERS*sizeof(struct PLAYER *));
// Allocate each line of M `PLAYER` structs.
// Basically we allocate N chunks of memory big enough to contain M PLAYER structs one next each other.
// What we get is something like this:
//
// pointer pointers PLAYER lines
// of pointers array
// [addrP] -> [addr0] -> [PLAYER0 PLAYER1 PLAYER2] .. M
// [addr1] -> [PLAYER0 PLAYER1 PLAYER2] .. M
// ...N
//
int id = 0;
for (int i = 0; i < N_POINTERS; ++i)
{
pointers[i] = malloc(M_PLAYERS_PER_LINE*sizeof(struct PLAYER));
// Set the data you want to the structs.
for (int k = 0; k < M_PLAYERS_PER_LINE; ++k)
{
pointers[i][k].id = id++;
pointers[i][k].score = 123 + k;
pointers[i][k].age = 33 + i;
}
}
// Print data.
// Here we use a single PLAYER pointer that will
// traverse the entire PLAYER matrix.
struct PLAYER * player;
for (int i = 0; i < N_POINTERS; ++i)
{
for (int k = 0; k < M_PLAYERS_PER_LINE; ++k)
{
// Assign the current PLAYER to our pointer.
player = pointers[i] + k;
// Print PLAYER data, by reading the pointed struct.
printf("Player: #%i age:%i score:%d\n", player->id, player->age, player->score);
}
}
// Deallocate!
for (int i = 0; i < N_POINTERS; ++i)
{
// Deallocate each line chunk.
free(pointers[i]);
}
// Deallocate the array of pointers.
free(pointers);
return 0;
}
As a bonus track, if you need to allocate a matrix of M*N PLAYER structs, you should also look at this code, that will allocate M*N PLAYER structs into one unique memory block, one next each other, which is much more easier to manage, as you can see by the code itself:
#include <stdlib.h>
#include <stdio.h>
#define LINES 4
#define COLUMNS 3
#define GET_ARRAY_POS(lin, col) (col+(lin*COLUMNS))
struct PLAYER
{
int id;
int score;
int age;
};
int
main()
{
// Allocate a *FLAT* array of PLAYER structs, big enough to
// contain N*M PLAYER structs, one next each other.
struct PLAYER * array = malloc(LINES*COLUMNS*sizeof(struct PLAYER));
// Set the data you want to the structs.
int id = 0;
for (int lin = 0; lin < LINES; ++lin)
{
for (int col = 0; col < COLUMNS; ++col)
{
int pos = GET_ARRAY_POS(lin, col);
array[pos].id = id++;
array[pos].score = 123 + col;
array[pos].age = 33 + lin;
}
}
// Print data.
// Here we use a single PLAYER pointer that will
// traverse the entire PLAYER matrix.
for (int i = 0; i < (LINES*COLUMNS); ++i)
{
// Print PLAYER data, by reading the pointed struct.
printf("Player: #%i age:%i score:%d\n", array[i].id, array[i].age, array[i].score);
}
// Deallocate!
free(array);
return 0;
}
Enjoy! ^_^

Variable array size in c

I'm trying to declare arrays with a variable size, given by user input.
So far I have something like this:
typedef struct _object{
int rowsAmount;
int columsAmount;
int* rows;
int* colums;
} object;
object* newObject(int ra, int ca){
object* o = malloc(sizeof(object));
o->rowsAmount = ra;
o->columsAmount = ca;
o->rows = [ra];
o->colums = [ca];
return o;
}
int main(){
newObject(3,4);
}
I expected this wouldn't work, but I want something like this, and I don't know how to do it.
It looks like you're basically implementing a dynamic Matrix object here. You want something like:
typedef struct _object{
int rowsAmount;
int columsAmount;
int* matrix;
int** rows;
} object;
object* newObject(int ra, int ca){
object* o = malloc(sizeof(object));
o->rowsAmount = ra;
o->columsAmount = ca;
o->matrix = malloc(ra * ca * sizeof(int));
o->rows = malloc(ra * sizeof(int*));
for (size_t i = 0; i != ra; ++i) o->rows[i] = o->matrix + (i * ca);
return o;
}
You should also create a destructor function destroyObject, which similarly frees all the memory allocated for o and o->matrix.
Edit:
However, your comment that:
"I'm just trying to learn c, this is only about the setting the size.
I just happened to try it with 2 arrays"
...makes this question somewhat confusing, because it indicates you are not, in fact, trying to create a matrix (2D array) despite your use of "row"/"column" terminology here, but that you simply want to understand how to dynamically allocate arrays in C.
If that's the case, an array in C is dynamically allocated using a pointer variable and malloc:
size_t array_size = 10; /* can be provided by user input */
int* array = malloc(sizeof(int) * array_size);
And then later, the dynamically-allocated array must be freed once you are finished working with it:
free(array);
To dynamically allocate a 2d array of data in C:
Allocate the memory for the entire data. That memory is pointed to by arrayData.
Allocate an 1D Array of pointers one for each row
Point those pointers to the memory address corresponding each row
Code:
int *arrayData = malloc(sizeof(int) * rows * columns);
int **array = malloc(sizeof(int*) * rows);
for(int i=0; i < rows;++i){
array[i] = arrayData + i * columns;
}
You can now access the memory as array[row][col].
You can create a array with size input from user with out a structure.
int *array1;
int size;
// get input from user
array1 = malloc(sizeof(int)*size);
// do your stuff
free(array1);
if you want a 2D array,
int **array2;
int row, col;
int i;
array2 = malloc(sizeof(int*)*row);
for(i=0;i<row;++i)
array2[i] = malloc(sizeof(int)*col);
//use the array
for(i=0;i<row;++i)
free(array2[i]);
free(array2);
if you really need a structure array, then allocate memory for it in your newObject() function
typedef struct _object{
int rowsAmount;
int columsAmount;
int** array;
//int* colums;
} object;
object* newObject(int ra, int ca){
int i;
object* o = malloc(sizeof(object));
o->rowsAmount = ra;
o->columsAmount = ca;
o->array = malloc(sizeof(int*)*ra);
for(i=0;i<ra;i++)
o-<array[i]=malloc(sizeof(int)*ca);
return o;
}
int main(){
newObject(3,4);
}
I think that quite often people use dynamic memory allocation when scoped variables can be used instead. For example, array sized from user's input can be allocated on stack without using malloc/free:
int array_size;
scanf("%d", &array_size);
if (array_size > 0) {
/* Allocate array on stack */
float array[array_size];
/* ... do smth with array ... */
}
/* Out of scope, no need to free array */
Of course if your data block is huge, heap memory is a must, but for small allocations scopes are just fine.
Easiest way is to use boost::multi_array
Not only will you get any number of dimensions, it's also stored very efficiently as a single contiguous block of memory rather than n dimensional array.
CPU's are designed to traverse arrays quickly, and you could potentially utilise caching/prefetch/pipelining features of the compiler using this.
Eg
// 2 dimensions
int xDim;
int yDim;
cin >> xDim; // From user..
cin >> yDim;
// Initialise array
boost::multi_array<int,2> my2dgrid(boost::extents[xDim][yDim]);
// Iterate through rows/colums
for(int j = 0 ; j < yDim-1; j++) { // Row traversal
for(int i = 0 ; i < xDim-1; i++) { // Column traversal
int value = grid[j][i]; // Get a value
grid[j][i] = 123; // set a value
// Do something...
}
#include <stdio.h>
#include <stdlib.h>
typedef struct _object{
int rowsAmount;
int columsAmount;
int **rows;
// int* colums;
} object;
object* newObject(int ra, int ca){
int r;
object* o = malloc(sizeof(object));
o->rowsAmount = ra;
o->columsAmount = ca;
o->rows = (int **)malloc(ra*sizeof(int *));
for(r=0;r<ra;++r)
o->rows[r] = (int*)malloc(ca*sizeof(int));
return o;
}
int main(){
object *obj= newObject(3,4);
obj->rows[2][3]=5;
return 0;
}

Transferring data from 2d Dynamic array in C to CUDA and back

I have a dynamically declared 2D array in my C program, the contents of which I want to transfer to a CUDA kernel for further processing. Once processed, I want to populate the dynamically declared 2D array in my C code with the CUDA processed data. I am able to do this with static 2D C arrays but not with dynamically declared C arrays. Any inputs would be welcome!
I mean the dynamic array of dynamic arrays. The test code that I have written is as below.
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <stdlib.h>
const int nItt = 10;
const int nP = 5;
__device__ int d_nItt = 10;
__device__ int d_nP = 5;
__global__ void arr_chk(float *d_x_k, float *d_w_k, int row_num)
{
int index = (blockIdx.x * blockDim.x) + threadIdx.x;
int index1 = (row_num * d_nP) + index;
if ( (index1 >= row_num * d_nP) && (index1 < ((row_num +1)*d_nP))) //Modifying only one row data pertaining to one particular iteration
{
d_x_k[index1] = row_num * d_nP;
d_w_k[index1] = index;
}
}
float **mat_create2(int r, int c)
{
float **dynamicArray;
dynamicArray = (float **) malloc (sizeof (float)*r);
for(int i=0; i<r; i++)
{
dynamicArray[i] = (float *) malloc (sizeof (float)*c);
for(int j= 0; j<c;j++)
{
dynamicArray[i][j] = 0;
}
}
return dynamicArray;
}
/* Freeing memory - here only number of rows are passed*/
void cleanup2d(float **mat_arr, int x)
{
int i;
for(i=0; i<x; i++)
{
free(mat_arr[i]);
}
free(mat_arr);
}
int main()
{
//float w_k[nItt][nP]; //Static array declaration - works!
//float x_k[nItt][nP];
// if I uncomment this dynamic declaration and comment the static one, it does not work.....
float **w_k = mat_create2(nItt,nP);
float **x_k = mat_create2(nItt,nP);
float *d_w_k, *d_x_k; // Device variables for w_k and x_k
int nblocks, blocksize, nthreads;
for(int i=0;i<nItt;i++)
{
for(int j=0;j<nP;j++)
{
x_k[i][j] = (nP*i);
w_k[i][j] = j;
}
}
for(int i=0;i<nItt;i++)
{
for(int j=0;j<nP;j++)
{
printf("x_k[%d][%d] = %f\t",i,j,x_k[i][j]);
printf("w_k[%d][%d] = %f\n",i,j,w_k[i][j]);
}
}
int size1 = nItt * nP * sizeof(float);
printf("\nThe array size in memory bytes is: %d\n",size1);
cudaMalloc( (void**)&d_x_k, size1 );
cudaMalloc( (void**)&d_w_k, size1 );
if((nP*nItt)<32)
{
blocksize = nP*nItt;
nblocks = 1;
}
else
{
blocksize = 32; // Defines the number of threads running per block. Taken equal to warp size
nthreads = blocksize;
nblocks = ceil(float(nP*nItt) / nthreads); // Calculated total number of blocks thus required
}
for(int i = 0; i< nItt; i++)
{
cudaMemcpy( d_x_k, x_k, size1,cudaMemcpyHostToDevice ); //copy of x_k to device
cudaMemcpy( d_w_k, w_k, size1,cudaMemcpyHostToDevice ); //copy of w_k to device
arr_chk<<<nblocks, blocksize>>>(d_x_k,d_w_k,i);
cudaMemcpy( x_k, d_x_k, size1, cudaMemcpyDeviceToHost );
cudaMemcpy( w_k, d_w_k, size1, cudaMemcpyDeviceToHost );
}
printf("\nVerification after return from gpu\n");
for(int i = 0; i<nItt; i++)
{
for(int j=0;j<nP;j++)
{
printf("x_k[%d][%d] = %f\t",i,j,x_k[i][j]);
printf("w_k[%d][%d] = %f\n",i,j,w_k[i][j]);
}
}
cudaFree( d_x_k );
cudaFree( d_w_k );
cleanup2d(x_k,nItt);
cleanup2d(w_k,nItt);
getch();
return 0;
I mean the dynamic array of dynamic arrays.
Well, that's exactly where the problem lies. A dynamic array of dynamic arrays consists of a whole bunch of disjoint memory blocks, one for each line in the array (as is clearly seen from the malloc inside you for loop in mat_create2). So you can't copy such a data structure to device memory with just one call to cudaMemcpy*. Instead, you have to do either
Also use dynamic arrays of dynamic arrays on CUDA. To do this, you have to basically recreate your mat_create2 function, using cudaMalloc instead of malloc, then copy each row seperately.
Use a "tight" 2d array on CUDA, like you do now (which is a good thing, at least performance-wise!). But if you keep using dyn-dyn-arrays on host memory, you still have copy each row seperately, like
for(int i=0; i<r; ++i){
cudaMemcpy(d_x_k + i*c, x_k[i], c*sizeof(float), cudaMemcpyHostToDevice)
}
You may wonder "why did it work with a static 2d array, then"? Well, static 2d arrays in C are proper, tight arrays that can be copied in one go. It's a bit confusing that these are indexed with exactly the same syntax as dyn-dyn arrays (arr[x][y]), because it actually works completely different.
But you should consider using tight arrays on host memory, too, perhaps with an object-oriented wrapper like
typedef struct {
float* data;
int n_rows, n_cols;
} tight2dFloatArray;
#define INDEX_TIGHT2DARRAY(arr, y, x)\
(arr).data[(y)*(arr).n_cols + (x)]
such an approach of course can be implemented much safer as a C++ class.
*You also can't copy it inside main memory with just one memcpy: that only copies the array of pointers, not the actual data.

C Programming weird struct setup

I am trying to build this project and for some reason the program hangs when I run it.
It works fine if i comment out the data cache lines. but it cannot make a call to makeCache for two different caches i dont know why any C experts know. Im new to c.
/*
* main.c
*
* Created on: Sep 16, 2010
* Author: TJ
*/
#include <stdlib.h>
#include <stdio.h>
typedef struct {
int tag;
int valid;
int LRU;
int offset;
}directoryBlock;
typedef struct{
int setNumber;
directoryBlock blocks[];
}cacheSet;
typedef struct{
int cacheNumber;
cacheSet *sets[];
}cache;
cache* makeCache(cache *makeMe,int numberOfSets, int blocksPerSet);
int main(void)
{
int i = 0;
//cache * temp = makeCache(10,200);
i = 0;
int j = 0;
cache *instructions = malloc(sizeof(cache) + sizeof(cacheSet*));
cache *data = malloc(sizeof(cache) + sizeof(cacheSet*));
makeCache(instructions,20,300);
makeCache(data,20,300);
for(j=0;j < 20;j++)
{
for(i = 0; i < 300;i++)
{
printf("Data From Set %d Block %d, Valid %d, Tag %d, LRU %d, Offset %d\n",j,i
,instructions->sets[j]->blocks[i].valid,instructions->sets[j]->blocks[i].tag
,instructions->sets[j]->blocks[i].LRU,instructions->sets[j]->blocks[i].offset);
}
}
return 0;
}
cache* makeCache(cache *makeMe,int numberOfSets,int blocksPerSet)
{
int i = 0;
int j = 0;
for(j=0; j < numberOfSets;j++)
{
cacheSet *newSet = malloc(sizeof(cacheSet) + sizeof(directoryBlock)*blocksPerSet);
for(i = 0; i < blocksPerSet; i++)
{
directoryBlock temp;
temp.LRU = i*j;
temp.tag = i*j;
temp.offset = i*j;
temp.valid = i;
newSet->blocks[i] = temp;
}
makeMe->sets[j] = newSet;
}
return makeMe;
}
You're not allocating space for the cacheSet array, you have 20 cacheSets so try this with the "20 *" added to your lines:
cache *instructions = malloc(sizeof(cache) + 20 *sizeof(cacheSet*));
cache *data = malloc(sizeof(cache) + 20 * sizeof(cacheSet*));
In your main function you're allocating the memory for your cache. Since you have a function dedicated to creating the cache, it should allocate the memory. That function has the parameters to determine the total memory required. If you do it separately, you're repeating that information and require yourself to remember exactly how to allocate the memory. If the function makeCache does it for you, it will save pain later. Just be sure your documentation notes that the makeCache function allocates memory.
Your cache memory is incorrect, but not as pointed out before. Just sizeof(cache) is the right size. This will make room for the int and the cacheSet **. You should then allocate memory for the cacheSet array in each cache. Then you should allocate memory for each directoryBlock in each cacheSet in the cache.... kittens, cats, sacks, and wives...
So all your allocations should just be Thing *t sizof(Thing);
In psuedocode:
cache *c = malloc(sizeof(cache))
for 0 to number of cacheSets:
cacheSet *s = malloc(sizeof(cacheSet))
for 0 to number of blocks:
block *b = malloc(sizeof(block))
//fill in data
JD

using malloc for block of structs

I am trying to allocate a block of memory, and store a list of structures without using multiple mallocs for each... this is just a generic example, I don't have the original code I was working with earlier, but this is the general idea, but my problem was that I was getting heap corruption when other parts of my code executed after the InitPoints() function call. I don't know what part of my code is illegal, but I suspect it is in the for loop of the InitPoints() function. I am trying to use this as table, then I can create additional tables of defined size if I ran out of memory and link them together... so kind of like a dynamic expanding array if that makes any sense.
typedef struct Tb{
POINT points;
POINT *next;
} TABLE;
typedef struct Pt{
int x;
int y;
}POINT;
POINT *mypoints;
int main() {
int size = 10;
int i = 0;
mypoints = InitPoints(size);
for(i=0; i < size; i++)
{
printf("mypoint [%d] = (%d,%d)\n",i, mypoints->x, mypoints->y);
mypoints = mypoints + sizeof(POINT);
}
// some other code...
// i.e. createThread(....)
return 0;
}
POINT* InitPoints(int size)
{
POINT *tmp;
POINT *orig;
int a = 10;
int b = 1000;
orig = (POINT*) malloc (sizeof(POINT) * size);
if(orig == NULL)
return NULL;
tmp = orig;
for (i = 0; i < size; i++)
{
tmp->x = a++;
tmp->y = b++;
tmp = tmp + sizeof(POINT);
}
return orig;
}
This is wrong:
mypoints = mypoints + sizeof(POINT);
You should review pointer arithmetic in C. Just use:
mypoints += 1; /* or something similar */
(There is a similar problem in your InitPoints function)
Here's one referemce:
http://www.eskimo.com/~scs/cclass/notes/sx10b.html
The problem is in this line:
tmp = tmp + sizeof(POINT);
It should be
++tmp;
The latter says to increment the pointer by one element; since it points to the structure, it increments by the size of the structure. The original code instead increments by n elements where n is the number of bytes in the structure. For example, if int is 32-bits, it will advanced by 8 elements.
This is why I would do it
for (i = 0; i < size; i++)
{
orig[i].x = a++;
orig[i].y = b++;
}
In C, adding an integer to a POINT* pointer advances the pointer not by that number of bytes, but by that number of POINT structures.
You have two places in your code where you add sizeof(POINT) to your pointer. Instead you should just add 1.

Resources