I'm in difficult to resolve this problem:
typedef struct {
.....
} info;
info array[1000][10][10]; //now i have this 3d matrix
For memory optimization i want to allocate dynamically the first dimension: i want to have a dynamic array of matrix[10][10]. So i have declare a pointer like this:
info *array[10][10];
But how to do a malloc do add for example N matrix[10][10] to the array?
I tried:
info *array[10][10]=malloc(N*sizeof(array));
As described by WhozCraig in the coments and kiranBiradar in his answer, your attempt to allocate:
info *array[10][10]=malloc(N*sizeof(array));
was an attempt to allocate for an array or pointer arrays. You were allocating for N 10x10 array of pointers.
What you intended was to allocate storage for N 10x10 info. To do so, you need to declare array as a pointer to array info [10][10]. Declared in this manner you are then free to allocate for N 10x10 array info in a single allocation (with the benefit of only requiring a single free (as opposed to allocating for info *** and requiring separate allocations for pointers, row-pointers, and finally elements-per-row). But to declare a pointer to array info [10][10], you must declare arrays as:
info (*array)[10][10];
(note: depending on how you use array throughout the code and whether initialization of all elements to some default value is beneficial, you can use calloc instead of malloc. calloc will allocate and zero all bytes (the additional time required to zero the new memory is generally negligible)).
And how can i do a realloc of array (in case i need more space)?
Since you have declared array as a pointer to array info[10][10] and have allocated storage in one shot, you simply need to realloc to create a larger block of memory for your storage. There are a number of allocation schemes to efficiently handle reallocation and you have the freedom to handle it however you want.
The rule-of-thumb is to generally declare storage for some reasonably anticipated number of pointers and 10x10 arrays of info. You keep a counter for the number of pointers and arrays currently allocated (say in nptrs). You keep a second counter of the number you have currently filled (say ndx -- short for index). When your index reaches the number of pointers and arrays allocated, you then realloc storage for somewhere between 1.5 - 2 times more storage, update your counter for nptrs and keep going until ndx == nptrs again, and repeat.
A short example may help. Since the members of info are undefined, lets just use a simple pointer to array int [10][10] for the example. The process would be the same for any collection, the only difference being sizeof *array would change the number of bytes allocated for each 10x10 array. (if you have additional members of info requiring dynamic allocation -- that would be an additional requirement)
When reallocating, always assign the return realloc to a temporary pointer. If realloc fails, it returns NULL and if you assign that to your original pointer -- you have just created a memory leak and lost the reference to your original block of memory. By using a temporary pointer, if realloc fails, your original data, and the pointer to it, remain valid.
A example that simply fills each 10x10 array with a constant number (e.g. 1, 2, 3, ...) and calls realloc twice to increase allocation for the 10x10 blocks from 8 to 16 and finally 32 would be:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NMTRX 8 /* if you need constants, then #define one (or more) */
#define MSIZE 10 /* don't use "magic numbers" in your code, unless */
#define NTEST 24 /* mandatory (like scanf field-width modifiers) */
/** set single MSIZExMSIZE array to n */
void set_m_to_n (int m[MSIZE][MSIZE], int n)
{
for (int i = 0; i < MSIZE; i++)
for (int j = 0; j < MSIZE; j++)
m[i][j] = n;
}
/** print single MSIZExMSIZE array */
void print_m (int m[MSIZE][MSIZE])
{
for (int i = 0; i < MSIZE; i++) {
for (int j = 0; j < MSIZE; j++)
printf (" %2d", m[i][j]);
putchar ('\n');
}
}
/** realloc to twice 'sz * *nelement' bytes returning
* pointer to reallocated block on success, NULL otherwise.
*/
void *realloc_2x (void *ptr, size_t sz, size_t *nelem)
{
char *memptr = realloc (ptr, 2 * *nelem * sz);
if (memptr == NULL) {
perror ("realloc-m");
return NULL;
} /* optionally zero all new memory */
memset (memptr + *nelem * sz, 0, *nelem * sz);
*nelem *= 2; /* update nelem (nptrs) to reflect new allocation */
return memptr; /* return pointer to new block for assignment */
}
int main (void) {
size_t ndx = 0, /* index */
nptrs = NMTRX; /* initial pointers to allocate */
int (*m)[MSIZE][MSIZE]; /* pointer to MSIZExMSIZE array */
m = calloc (nptrs, sizeof *m); /* allocate & initialize zero */
if (m == NULL) { /* validate allocation */
perror ("calloc-m");
exit (EXIT_FAILURE);
}
for (ndx = 0; ndx < NTEST; ndx++) { /* loop filling NTEST arrays */
if (ndx == nptrs) { /* check if index reached allocation */
void *tmp = realloc_2x (m, sizeof *m, &nptrs); /* realloc_2x */
if (tmp == NULL)/* validate reallocation */
break; /* don't exit on failure, original data good */
m = tmp; /* assign reallocated block to m */
}
set_m_to_n (m[ndx], ndx + 1); /* set array values to ndx+1 */
}
for (size_t i = 0; i < ndx; i++) { /* output all MSIZExMSIZE arrays */
printf ("\nm[%2zu]:\n", i);
print_m (m[i]);
}
free (m); /* free allocated memory */
return 0;
}
Example Use/Output
The output is simply the pointer and each 10x10 block of numbers:
$ ./bin/arr3d_dyn_ptr2d
m[ 0]:
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
m[ 1]:
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
...
m[23]:
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
In any code you write that dynamically allocates memory, you have 2 responsibilities regarding any block of memory allocated: (1) always preserve a pointer to the starting address for the block of memory so, (2) it can be freed when it is no longer needed.
It is imperative that you use a memory error checking program to insure you do not attempt to access memory or write beyond/outside the bounds of your allocated block, attempt to read or base a conditional jump on an uninitialized value, and finally, to confirm that you free all the memory you have allocated.
For Linux valgrind is the normal choice. There are similar memory checkers for every platform. They are all simple to use, just run your program through it.
Memory Use/Error Check
$ valgrind ./bin/arr3d_dyn_ptr2d
==25240== Memcheck, a memory error detector
==25240== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==25240== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==25240== Command: ./bin/arr3d_dyn_ptr2d
==25240==
m[ 0]:
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
m[ 1]:
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
...
m[23]:
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
24 24 24 24 24 24 24 24 24 24
==25240==
==25240== HEAP SUMMARY:
==25240== in use at exit: 0 bytes in 0 blocks
==25240== total heap usage: 3 allocs, 3 frees, 22,400 bytes allocated
==25240==
==25240== All heap blocks were freed -- no leaks are possible
==25240==
==25240== For counts of detected and suppressed errors, rerun with: -v
==25240== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Always confirm that you have freed all memory you have allocated and that there are no memory errors.
Look things over and let me know if you have further questions.
You can use the following solution:
info (*array)[10][10]=malloc(N*sizeof(*array)); //declares pointer to 2d array
Related
I am trying to parse a VTK file in C by extracting its point data and storing each point in a 3D array. However, the file I am working with has 9 shorts per point and I am having difficulty understanding what each number means.
I believe I understand most of the header information (please correct me if I have misunderstood):
ASCII: Type of file (ASCII or Binary)
DATASET: Type of dataset
DIMENSIONS: dims of voxels (x,y,z)
SPACING: Volume of each voxel (w,h,d)
ORIGIN: Unsure
POINT DATA: Total number of points/voxels (dimx.dimy.dimz)
I have looked at the documentation and I am still not getting an understanding on how to interpret the data. Could someone please help me understand or point me to some helpful resources
# vtk DataFile Version 3.0
vtk output
ASCII
DATASET STRUCTURED_POINTS
DIMENSIONS 256 256 130
SPACING 1 1 1.3
ORIGIN 86.6449 -133.929 116.786
POINT_DATA 8519680
SCALARS scalars short
LOOKUP_TABLE default
0 0 0 0 0 0 0 0 0
0 0 7 2 4 5 3 3 4
4 5 5 1 7 7 1 1 2
1 6 4 3 3 1 0 4 2
2 3 2 4 2 2 0 2 6
...
thanks.
You are correct regarding the meaning of fields in the header.
ORIGIN corresponds to the coordinates of the 0-0-0 corner of the grid.
An example of a DATASET STRUCTURED_POINTS can be found in the documentation.
Starting from this, here is a small file with 6 shorts per point. Each line represents a point.
# vtk DataFile Version 2.0
Volume example
ASCII
DATASET STRUCTURED_POINTS
DIMENSIONS 3 4 2
ASPECT_RATIO 1 1 1
ORIGIN 0 0 0
POINT_DATA 24
SCALARS volume_scalars char 6
LOOKUP_TABLE default
0 1 2 3 4 5
1 1 2 3 4 5
2 1 2 3 4 5
0 2 2 3 4 5
1 2 2 3 4 5
2 2 2 3 4 5
0 3 2 8 9 10
1 3 2 8 9 10
2 3 2 8 9 10
0 4 2 8 9 10
1 4 2 8 9 10
2 4 2 8 9 10
0 1 3 18 19 20
1 1 3 18 19 20
2 1 3 18 19 20
0 2 3 18 19 20
1 2 3 18 19 20
2 2 3 18 19 20
0 3 3 24 25 26
1 3 3 24 25 26
2 3 3 24 25 26
0 4 3 24 25 26
1 4 3 24 25 26
2 4 3 24 25 26
The 3 first fields may be displayed to understand the data layout : x change faster than y, which change faster than z in file.
If you wish to store the data in an array a[2][4][3][6], just read while doing a loop :
for(k=0;k<2;k++){ //z loop
for(j=0;j<4;j++){ //y loop : y change faster than z
for(i=0;i<3;i++){ //x loop : x change faster than y
for(l=0;l<6;l++){
fscanf(file,"%d",&a[k][j][i][l]);
}
}
}
}
To read the header, fscanf() may be used as well :
int sizex,sizey,sizez;
char headerpart[100];
fscanf(file,"%s",headerpart);
if(strcmp(headerpart,"DIMENSIONS")==0){
fscanf(file,"%d%d%d",&sizex,&sizey,&sizez);
}
Note than fscanf() need the pointer to the data (&sizex, not sizex). A string being a pointer to an array of char terminated by \0, "%s",headerpart works fine. It can be replaced by "%s",&headerpart[0]. The function strcmp() compares two strings, and return 0 if strings are identical.
As your grid seems large, smaller files can be obtained using the BINARY kind instead of ASCII, but watch for endianess as specified here.
I would like to do the following array extension using SIMD intrinsic.
I have two arrays:
cluster value (v_i): 10, 20, 30, 40
cluster length (l_i): 3, 2, 1, 2
I would like to create a resultant array containing the values: v_i repeated for l_i times, i.e:
result: 10, 10, 10, 20, 20, 30, 40, 40.
How can I compute this using SIMD intrinsic?
This may be optimized by SIMD if input array size is up to 8, output array size up to 16, and bytes as array values. At least SSSE3 is required. Extending this approach to larger arrays/elements is possible but efficiency will quickly degrade.
Compute prefix sum of array lengths. This may be quickly done if you reinterpret byte array of lengths as a single 64-bit (32-bit) word, multiply it by 0x101010101010100, and store the result in SIMD register.
Fill array of indexes (in single SIMD register) with average index (half-size of the array of prefix sums).
Perform binary search for proper index for each byte of index register (in parallel). This may be done by extracting appropriate byte of prefix sum register with PSHUFB instruction, comparing extracted prefix value with byte number using PCMPGTB (and optionally with PCMPEQB), then adding/subtracting half of index range.
(Optionally) fill all unused bytes of index register with 0xff.
Use PSHUFB to fill some register with values from cluster value array indexed by the index register.
Main loop of the algorithm (binary search) contains PSHUFB, PCMPGTB, and a few arithmetical and logical operations. It is executed log(input_array_size) times, most likely 2 or 3 times.
Here is an example:
cluster value: 10 20 30 40
cluster length: 3 2 1 2
prefix sum: 0 3 5 6 8
indexes: 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
prefix value: 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
byte number: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
mask: ff ff ff ff ff 0 0 0 0 0 0 0 0 0 0 0
indexes: 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3
prefix value: 3 3 3 3 3 6 6 6 6 6 6 6 6 6 6 6
byte number: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
mask: ff ff ff 0 0 ff 0 0 0 0 0 0 0 0 0 0
indexes: 0 0 0 1 1 2 3 3 3 3 3 3 3 3 3 3
length constrained: 0 0 0 1 1 2 3 3 ff ff ff ff ff ff ff ff
cluster value: 10 10 10 20 20 30 40 40 0 0 0 0 0 0 0 0
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 years ago.
Improve this question
Can you please tell me why I am always getting array a[i] in descending order only? Please help.
for(i=0;i<10;i++)
{
for (j=0;j<10;j++)
{
if(a[i]>=a[j])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
The problem is that your sorting runs two complete loops, comparing as for all pairs of i and j, including ones where i is greater than j (at which point you shouldn't be swapping the items). In order for selection sort * to work, it needs to pick its swap candidates only from the unsorted portion of the array.
Here is how to fix your implementation:
for(i=0;i<10-1;i++) // You do not need to touch the last element, so end at 10-1
{
for (j=i+1;j<10;j++) // Make it j = i+1
{
if(a[i] > a[j]) // >, not >= : no need to swap when two items are equal
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
* Selection Sort is the fancy name of the sorting algorithm that you are implementing.
Can you please tell me why I am always getting array a[i] in descending order only?
Because you implemented logic (comparisons) for descending order. Change
if(a[i]>=a[j])
to
if(a[i] < a[j])
See the code:
#include <stdio.h>
int main()
{
int a[10] = {3,15,9,4,15,65,0,2,1,1};
int temp;
for(int i=0;i<10;i++)
{
for (int j=0;j<10;j++)
{
if(a[j] > a[i])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
for(int i=0;i<10;i++)
printf("%d ", a[i]);
}
Here is the working code with output: http://ideone.com/DijpJD.
Steps of sorting process: Only those steps are shown where the changes has taken place.
Pass 1: 15 3 9 4 15 65 0 2 1 1
65 3 9 4 15 15 0 2 1 1
Pass 2: 3 65 9 4 15 15 0 2 1 1
Pass 3: 3 9 65 4 15 15 0 2 1 1
Pass 4: 3 4 65 9 15 15 0 2 1 1
3 4 9 65 15 15 0 2 1 1
Pass 5: 3 4 9 15 65 15 0 2 1 1
Pass 6: 3 4 9 15 15 65 0 2 1 1
Pass 7: 0 4 9 15 15 65 3 2 1 1
0 3 9 15 15 65 4 2 1 1
0 3 4 15 15 65 9 2 1 1
0 3 4 9 15 65 15 2 1 1
0 3 4 9 15 15 65 2 1 1
Pass 8: 0 2 4 9 15 15 65 3 1 1
0 2 3 9 15 15 65 4 1 1
0 2 3 4 15 15 65 9 1 1
0 2 3 4 9 15 65 15 1 1
0 2 3 4 9 15 15 65 1 1
Pass 9: 0 1 3 4 9 15 15 65 2 1
0 1 2 4 9 15 15 65 3 1
0 1 2 3 9 15 15 65 4 1
0 1 2 3 4 15 15 65 9 1
0 1 2 3 4 9 15 65 15 1
0 1 2 3 4 9 15 15 65 1
Pass 10: 0 1 1 3 4 9 15 15 65 2
0 1 1 2 4 9 15 15 65 3
0 1 1 2 3 9 15 15 65 4
0 1 1 2 3 4 15 15 65 9
0 1 1 2 3 4 9 15 65 15
0 1 1 2 3 4 9 15 15 65
I have an array like this but with more rows:
104,206 99,557 96,667 1 33 1 120,993 0
104,708 99,189 96,641 6 14 1 123,989 65536
107,099 102,732 98,641 0 46 1 118,899 131072
104,985 101,174 98,251 5 30 2 118,445 196608
108,86 103,355 103,494 0 21 1 118,423 262144
I need a loop which delete all the rows when in the 4th column is a 0.
I need do this with all the rows and the result is as follows:
104,206 99,557 96,667 1 33 1 120,993 0
104,708 99,189 96,641 6 14 1 123,989 65536
104,985 101,174 98,251 5 30 2 118,445 196608
In a single line (using logical indexing):
data(data(:,4)==0,:) = [];
Example:
>> data = [5 8 6 0 9
1 3 3 5 2
4 5 6 0 8
2 2 7 3 5];
>> data(data(:,4)==0,:) = []
data =
1 3 3 5 2
2 2 7 3 5
data = randi(10,1000,10) -1; % random data
marks = find(data(:,4)); % find only returns non-zero elements
clean_data = data(marks,:); % return all data on row /marks/
I'm working on J.
How can I convert this matrix:
(i.10)*/(i.10)
0 0 0 0 0 0 0 0 0 0
0 1 2 3 4 5 6 7 8 9
0 2 4 6 8 10 12 14 16 18
0 3 6 9 12 15 18 21 24 27
0 4 8 12 16 20 24 28 32 36
0 5 10 15 20 25 30 35 40 45
0 6 12 18 24 30 36 42 48 54
0 7 14 21 28 35 42 49 56 63
0 8 16 24 32 40 48 56 64 72
0 9 18 27 36 45 54 63 72 81
in array?
0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 . . .
I tried
(i.10)*/(i.10)"0
and then I've added
~.(i.10)*/(i.10)"0
to eliminate doubles, but it doesn't work.
If you want to turn a 2-dimensional table (matrix) into a 1-dimensional list (vector or "array", though in the J world "array" usually means "rectangle with any number [N] of dimensions"), you can use ravel (,):
matrix =: (i.10)*/(i.10)
list =: , matrix
list
0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 ...
Now using nub (~.) to remove duplicates should work:
~. list
0 1 2 3 4 5 6 7 8 9 10 12 ...
Note that, in J, the shape of an array usually carries important information, so flattening a matrix like this would be fairly unusual. Still, nothing stopping you.
BTW, you can save yourself some keystrokes by using the adverb ~, which will copy the left argument of a dyad to the right side as well, so you could just say:
matrix =: */~ i. 10
and get the same result as (i.10) */ (i.10).