I am trying to sort a buffer full of variable-length records alphabetically in C++. I previously asked how to implement this, and was told to sort an array of pointers to the records. I set up an array of pointers, but realized that each pointer points to the beginning of a record, but there is no way of it knowing when the record stops. When I try to print out the record pointed to by each pointer in the array, therefore, for each pointer, I get the entire buffer of all records, starting from the one pointed to. (For example, if the buffer holds "Helloworld", and there is a pointer at each letter, printing the array of pointers would produce "Helloworldelloworldlloworldloworldoworldworldorldrldldd".) Obviously, this is not what I want; also, the qsort does not seem to be working on the array of pointers either. When I debug, the memory spaces pointed to by the pointers seem to hold very odd characters that are definitely not part of the ascii character set and were not included in my input file. I am very confused. Below is my code; how can I do this without getting the odd results I get now? Thank you so much, bsg.
int _tmain(int argc, _TCHAR* argv[])
{
//allocate memory for the buffer
buff = (unsigned char *) malloc(2048);
realbuff = (unsigned char *) malloc(NUM_RECORDS * RECORD_SIZE);
fp = fopen("postings0.txt", "r");
if(fp)
{
fread(buff, 1, 2048, fp);
/*for(int i=0; i <30; i++)
cout << buff[i] <<endl;*/
int y=0;
//create a pointer to an array of unsigned char pointers
unsigned char *pointerarray[NUM_RECORDS];
//point the first pointer in the pointer array to the first record in the buffer
pointerarray[0] = &buff[0];
int recordcounter = 1;
//iterate through each character in the buffer;
//if the character is a line feed (denoting a new record),
// point the next pointer in the pointer array to the next
//character in the buffer (that is, the start of the next record)
for(int i=0;i <2048; i++)
{
if(buff[i] == char(10))
{
pointerarray[recordcounter] = &buff[i+1];
recordcounter++;
}
}
//the actual qsort (NUM_RECORDS is a constant declared above; omitted here)
qsort(pointerarray, NUM_RECORDS, sizeof(char*), comparator);
}
else
cout << "sorry";
cout << sizeof(pointerarray)/sizeof(char*);
for(int k=0; k < sizeof(pointerarray)/sizeof(char*);k++)
{
cout << pointerarray[k];
}
int comparator(const void * elem1, const void * elem2)
{
//iterate through the length of the first string
while(*firstString != char(10))
{
return(strcmp(firstString, secondString));
firstString++;
secondString++;
/
}
return 0;
}
I'm guessing the problem is in your comparator function (which doesn't compile as posted).
qsort gives a pointer to the array element to the comparator function. In your case that would be a pointer to the char* stored in the array.
The man page for qsort gives this example:
static int
cmpstringp(const void *p1, const void *p2)
{
/* The actual arguments to this function are "pointers to
pointers to char", but strcmp(3) arguments are "pointers
to char", hence the following cast plus dereference */
return strcmp(* (char * const *) p1, * (char * const *) p2);
}
int
main(int argc, char *argv[])
{
int j;
assert(argc > 1);
qsort(&argv[1], argc - 1, sizeof(char *), cmpstringp);
for (j = 1; j < argc; j++)
puts(argv[j]);
exit(EXIT_SUCCESS);
}
This question basically comes down to 'how do you know the length of your variable-length record.' There needs to be some way to tell, either from the record itself, or from some other data.
One way is to use pointer/length pairs to refer to records -- a pointer to the beginning of the record and a length (int or size_t), which you store together in a struct. With C++ you can use std::pair, or with C define a litte struct. You can then use qsort on an array of these.
In your case, you can tell the length by looking for a char(10), as you always use them to terminate your strings. You need a custom comparison (strcmp won't work -- it expects NUL terminators) that is aware of this.
Related
I am trying to read 1244 bytes at a time from a file. Essentially, the idea is to segment the 100KB worth of data into packets. So the approach I am taking is, assigning all the data to an array and then creating an array of pointers which will contain starting positions to each of my packets. The pointer array contains values [0, 1244, 2488, and so on].
It works perfectly fine, except my first assignment is gibberish. k[0] and o[0] both come up with garbage while the remaining 79 values seem to be fine. Can anyone assist?
I realize the first argument to the fread command should be a pointer, but this worked also. Also, I need the pointers to the starting of each of my packets because I am doing other function calls (omitted from code) that format the packet properly with the appropriate headers.
It's been a while since I coded in c/c++ so any optimizations you could provide, would be much appreciated.
int main(int argc, const char * argv[])
{
FILE *data;
int size; int i;
int paySize = 1244;
//int hdrSize = 256;
data = fopen("text2.dat","r");
//get data size
fseek(data, 0, SEEK_END);
size = ftell(data);
rewind (data);
char k[size]; //initializing memory location for all the data to be read in.
fread(k, 1, size, data); //reading in data
int temp = ceil(size/paySize);
char * o[temp]; //array of pointers to beginning of each packet.
int q = 0;
for (i = 0; i < size; i = i+paySize)
{
o[q] = &k[i];
q++;
}
cout << o[0] << endl; //this outputs gibberish!
cout << o[0] << endl;
prints an address to which this pointer points. To print value at this address use:
cout << *o[0] << endl;
Here:
char k[size];
char * o[temp];
o[q] = &k[i];
you assign to o[] pointers to characters, dereferencing such a pointer result in a single char.
I am trying to create a multimap indexed on a C-style string, as shown in the following code segment:
#include <cstring>
#include <map>
#include <iostream>
using namespace std;
int main(void)
{
int i, j;
int (*fn_pt)(const char *, const char *) = strcmp;
multimap<char *, char *, int (*)(const char *, const char *)>a(fn_pt);
for (i = 0; i < 2; i++)
{
char key[2];
sprintf(key, "%d", i);
for (j = 0; j< 5; j++)
{
char value[2];
sprintf(value, "%d", j);
a.insert(pair<char *, char *>(key, value));
}
}
for (i = 0; i < 2; i++)
{
char key[2];
sprintf(key, "%d", i);
multimap<char *, char *>::iterator it = a.find(key);
while (it != a.end())
{
cout << it->first << "\t" << it->second <<endl;
it++;
}
}
}
Simply changing the key in the above program to integer gives me the expected result. But, indexing the multimap on a string is giving me something unexpected (only rows of 1's and 4's separated by space), instead of showing me every value for every key value used.
Where am I going wrong in this?
Thanks
strcmp is a wrong predicate to use in multimap.
The predicate shall satisfy the following:
The expression comp(a,b), where comp is an object of this comparison class and a and b are key values, shall return true if a is to be placed at an earlier position than b in a strict weak ordering operation.
strcmp violates that because it returns a nonzero value if the strings are unequal, either a < b or a > b.
You should define your own predicate which returns true if and only if the first string is less than the second.
multimap<char *, char *, int (*)(const char *, const char *)>a(fn_pt);
for (i = 0; i < 2; i++)
{
char key[2];
sprintf(key, "%d", i);
for (j = 0; j< 5; j++)
{
char value[2];
sprintf(value, "%d", j);
a.insert(pair<char *, char *>(key, value));
}
}
You're storing two pointers in a container, and then you're destroying the objects (key and value) those pointers point to when they go out of scope. This leaves the container holding information that is now meaningless.
You're using the memory of key and value long after they go out of scope. In fact, all your char* pointers point at the same piece of stack memory, and that piece is ready to be reused by the time you actually look at it.
To do what you want you need to use strdup() to create a permanent copy of your char * data. Of course, then you need to worry about deallocating it later.
I want to create jagged character two dimensional array in c++.
int arrsize[3] = {10, 5, 2};
char** record;
record = (char**)malloc(3);
cout << endl << sizeof(record) << endl;
for (int i = 0; i < 3; i++)
{
record[i] = (char *)malloc(arrsize[i] * sizeof(char *));
cout << endl << sizeof(record[i]) << endl;
}
I want to set record[0] for name (should have 10 letter), record[1] for marks (should have 5 digit mark )and record[3] for Id (should have 2 digit number). How can i implement this? I directly write the record array to the binary file. I don't want to use struct and class.
in C++ it would like this:
std::vector<std::string> record;
Why would you not use a struct when it is the sensible solution to your problem?
struct record {
char name[10];
char mark[5];
char id[2];
};
Then writing to a binary file becomes trivial:
record r = get_a_record();
write( fd, &r, sizeof r );
Notes:
You might want to allocate a bit of extra space for NUL terminators, but this depends on the format that you want to use in the file.
If you are writing to a binary file, why do you want to write mark and id as strings? Why not store an int (4 bytes, greater range of values) and a unsigned char (1 byte)
If you insist on not using a user defined type (really, you should), then you can just create a single block of memory and use pointer arithmetic, but beware that the binary generated by the compiler will be the same, the only difference is that your code will be less maintainable:
char record[ 10+5+2 ];
// copy name to record
// copy mark to record+10
// copy id to record+15
write( fd, record, sizeof record);
Actually the right pattern “to malloc” is:
T * p = (T *) malloc(count * sizeof(T));
where T could be any type, including char *. So the right code for allocating memory in this case is like that:
int arrsize[3] = { 10, 5, 2 };
char** record;
record = (char**) malloc(3 * sizeof(char *));
cout << sizeof(record) << endl;
for (int i = 0; i < 3; ++i) {
record[i] = (char *) malloc(arrsize[i] * sizeof(char));
}
I deleted cout'ing sizeof(record[i]) because it will always yield size of (one) pointer to char (4 on my laptop). sizeof is something that plays in compiling time and has no idea how much memory pointed by record[i] (which is really a pointer - char * type) was allocated in the execution time.
malloc(3) allocates 3 bytes. Your jagged array would be an array containing pointers to character arrays. Each pointer usually takes 4 bytes (on a 32-bit machine), but more correctly sizeof(char*), so you should allocate using malloc(3 * sizeof(char*) ).
And then record[i] = (char*)malloc((arrsize[i]+1) * sizeof(char)), because a string is a char* and a character is a char, and because each C-style string is conventionally terminated with a '\0' character to indicate its length. You could do without it, but it would be harder to use for instance:
strcpy(record[0], name);
sprintf(record[1], "%0.2f", mark);
sprintf(record[2], "%d", id);
to fill in your record, because sprintf puts in a \0 at the end. I assumed mark was a floating-point number and id was an integer.
As regards writing all this to a file, if the file is binary why put everything in as strings in the first place?
Assuming you do, you could use something like:
ofstream f("myfile",ios_base::out|ios_base::binary);
for (int i=0; i<3; i++)
f.write(record[i], arrsize[i]);
f.close();
That being said, I second Anders' idea. If you use STL vectors and strings, you won't have to deal with ugly memory allocations, and your code will probably look cleaner as well.
I'd like to test a function that takes runtime-allocated multidimensional arrays, by passing it a hardcoded array.
The function has a signature of void generate_all_paths(int** maze, int size) and the array is defined as int arr[5][5] = {REMOVED}.
I'm not exactly sure how to properly coerce the array for the function (or if that is impossible).
This multi dimensional array topic unfortunately confuses so many C++ programmers. Well, here is the solution:
void generate_all_paths(int (*maze)[5], int size);
That is what the function declaration has to look like. An alternative, but fully equivalent is
void generate_all_paths(int maze[][5], int size);
Both are creating a parameter that is a pointer to an array of 5 integers. You can then pass your array of arrays of 5 integers to that function:
generate_all_paths(arr, 5);
Because your array's first element is an array of 5 integers, it will be converted automatically (implicitly) to a pointer to that first element when passed to that function.
In the comments, you have shown you are bound to an int**, because both your inner and outer dimension must have runtime values. A multi-dimensional array can not be used anymore. What you can do for testing purposes then is to create an array of pointers like this:
int store[5 * 5] = { ..... };
int *arr[5] = { store, store + 5, store + 10, store + 15, store + 20 };
Then, actually, you can have your function accept a int**. As the first element of you array then is a int*, it will be converted to a int** automatically. Another way of doing this is keeping the data in the 2 dimensional array, but just creating a "view" structured of pointers to that array:
int *arr[5] = { store[0], store[1], store[2], store[3], store[4] };
Where store is your int[5][5] array. Since store[n] accesses the n'th sub-array of that two-dimensional array and the element type of it is int, the pointer-converted type of it is int*, which will be compatible again.
You can write:
void display(char **a)
And then use a[i][j] to refer to elements in it.
The declaration char ** means "pointer to pointer to integer". To break it down into steps:
char *b = a[i];
That gets you a pointer to the first element of the i'th array in the array-of-arrays.
char c = b[j];
That gets you the j'th element in the array b.
The next problem you'll have is of allocating such an array-of-arrays.
char **arrayOfArrays = new char *[10];
for (int n = 0; n < 10; n++)
arrayOfArrays[n] = new char[20];
That allocates an array of 10 arrays, each "child" array having 20 characters.
In C/C++, array access syntax is just a way of retrieving a value some distance away from a pointer.
char *p = "Hello";
char *pl = p + 2; // get pointer to middle 'l'
char l = *pl; // fetch
char o = p[4]; // use array syntax instead
void display(char ** array)
should work. Also I don't think that it is a reserved word in standard C/C++.
And also, why is array a reserved word?
It isn't. You are probably using Visual Studio where it's displayed as a keyword due to its use in C++/CLI as a native managed type. However, this is irrelevant for C++ and Visual Studio is misleading in that regard.
As to your problem: You can simply pass a pointer-to-pointers-to-char and then pass your nested array directly (provided you are working with a dynamically allocated array):
void display(char** array) …
That said, your function assumes a fixed, known array length and some other details. Better would be to use a nested std::vector, or std::string (for instance). Using such existing data types makes your life much easier.
void display(std::vector<std::string> const& array) {
for (size_t i = 0; i < array.length(); ++i)
cout << array[i] << endl;
}
To take advantage of this, your calling code needs to be changed as well to use these data structures instead of plain C arrays on chars.
The Earwicker's answer is missing an important fact. What he is proposing is an array of arrays. For the first this wastes memory for the array of pointers ("char **arrayOfArrays = new char *[10]" is the creation point of this). For the second the array of chars may then not be a continuous block of memory, which is often a problem.
The only workaround in C++ is to create a one dimensional array and calculate the indexes when you need them.
char *b = new char[width*height];
then you can refer to element x,y (x is along width, y along height) like this
char c=b[width*y+x];
This may be however a bit slower than the solution above (measured on GCC 3.4.5), so if you are not interested in continuous memory (for example you always access the elements with [][], never by adding integer to a pointer and dereferencing it), then you should use the array af arrays. However, if you are interested in having the continuous memory, e.g. to pass it as initializer to an std::string object or to send it as a whole through a network, you should use the second one.
The best is to use pointers, but Borland C++ admits passing arrays as parameters for functions. Look at this code (includes: iostream and conio):
////////////////////////////////////////////
void ReceivedArray(char x[5]){
for (int i=0; i<5; i++ )
cout << x[i];
}
void main(){
char *x = new char[5];
for (int i=0; i<5; i++ )
x[i]='o';
ReceivedArray(x);
getchar();
}
///////////////////////////////////////////////////////////////
For passing 2D arrays (oops! some lines in spanish, sorry!):
(includes: iostream, stdlb, stdio and math)
/////////////////////////////////////////////////
using namespace std;
void ver(int x[][20]){
for(int i=0; i<15; i++) {
for(int j=0; j<20; j++) {
cout<< x[i][j] <<" "; }
cout << "\n"; }
}
void cambiar0(int x[][20]){ int n[255];
for (int i=255; i>=0; i--)
n[255-i]=i;
for(int i=0; i<15; i++)
for(int j=0; j<20; j++)
for(int k=0; k<255; k++)
if(x[i][j]==n[k]) {
x[i][j]=k; break; }
}
int main(int argc, char* argv[]){
int x[15][20]; char a;
for(int i=0; i<15; i++)
for(int j=0; j<20; j++)
x[i][j]=rand()%255;
cout << "¿desea ver la matriz? s/n ";
cin >> a;
if(a=='s') ver(x);
cambiar0(x);
cout << "\n\n";
cout << "¿desea ver la matriz? s/n ";
cin >> a;
if(a=='s') ver(x);
system("PAUSE"); return 0;
}
///////////////////////////////////
Hope this is what you meant.
arr is a pointer to the multi-dimesional array you have and is actually a pointer to an int. Now since your function accepts a pointer to an int pointer, you need to get the address of arr using: &arr and pass that to the function so that you will have this code:
To coerce the array: Pass &arr to the function.
To reference the array inside the func: *maze[x][y]
There is a pointer-to-an-Array of Arrays i.e. NameList in the code. I want the contents of each of the Arrays in the Pointer(NameList) to get printed one by one. The below code is not able do the task. Pls. help.
int Data1[] = {10,10};
int Data2[] = {20,20};
int Data3[] = {30,30};
int *NameList[] = {Data1, Data2, Data3};
main()
{ Function(NameList); }
Function(int *ArrayPointer)
{
int i, j, index=0;
for (i=0; i < 3; i++)
{
for (j=0; j < 2; j++)
{
//It does not print the data
printf("\nName: %s", ArrayPointer[index++]);
}
index=0; //Counter reset to 0
ArrayPointer++; //Pointer is incremented by one to pick next array in the pointer
}
}
print("code sample");
Another note from the original poster of the question:
I have completed a pacman game in Turbo C. I was polishing some graphics routines so that it can be reused again easily. This is only a small sample created for the purpose of help and understanding the concept. All data in the code actually are char arrays for sprites. Now i simply want to call a function passing the pointer so that each arrays in the pointer are drawn to the screen. How can this code be modified to handle this? Im actually stuck up here.
Darn it litb, once again you beat me to the punch by mere minutes. (If only I didn't have kids who keep waking up...)
Ahh, what the hell. Perhaps this will still be useful to somebody.
Oh, and just to nail this thing down:
Arrays, such as int a[4] allocate memory space for their data.
Pointers, such as int * p allocate just enouch memory space for a pointer to another spot in memory.
That's why we can use sizeof on arrays and get the full memory footprint, but not on pointers.
Other than that little distinction, there really isn't a big difference between int[] and int*. (Consider how many folks declare *main(int argc, char **argv) vs main(int argc, char * argv[]).)
ATTENTION: All memory addresses here are fictional. I'm just making them up to illustrate a point.
Given:
int Data1[] = {10,11};
int Data2[] = {20,22};
int Data3[] = {30,33};
We now have 3 blocks of memory. Say:
0xffff0000-0xffff0003 with a value of (int)(10)
0xffff0004-0xffff0007 with a value of (int)(11)
0xffff0008-0xffff000b with a value of (int)(20)
0xffff000c-0xffff000f with a value of (int)(22)
0xffff0010-0xffff0013 with a value of (int)(30)
0xffff0014-0xffff0017 with a value of (int)(33)
Where:
Data1 == & Data1 [0] == 0xffff0000
Data2 == & Data2 [0] == 0xffff0008
Data3 == & Data3 [0] == 0xffff0010
NO, I'm not going to get into big-endian vs little-endian byte ordering here!
Yes, in this case, Data1[2] == Data2[0]. But you can't rely on your compiler laying things out in memory the same way I've laid them out here.
Next:
int *NameList[] = {Data1, Data2, Data3};
So we now have another block of memory. Say:
0xffff0018-0xffff001b with a value of (int*)(0xffff0000)
0xffff001c-0xffff001f with a value of (int*)(0xffff0008)
0xffff0020-0xffff0023 with a value of (int*)(0xffff0010)
Where:
NameList == & NameList [0] == 0xffff0018
Note that NameList is of int ** type, and NOT int* type!
We can then write:
void Function(int **ArrayPointer)
{
for ( int i=0; i < 3; i++ )
for ( int j=0; j < 2; j++)
printf("Name: %d\n", ArrayPointer[i][j] );
}
int main() { Function(NameList); }
ArrayPointer resolves to (int**)0xffff0018.
ArrayPointer[0] == *( (int**) 0xffff0018 ) == (int*)(0xffff0000) == Data1.
ArrayPointer[0][1] == *( ( * (int**) 0xffff0018 ) + 1 ) == (int) * ( (int*)0xffff0000 + 1 ) == (int) * (int*) 0xffff0004 == Data1[1].
You may want to review pointer arithmetic: array[N] == *( array + N )
main has to return a type. You forget to put "int" as a return type (implicit int in C++ is banned).
Having said that, i'm not sure what you mean by
// It does not print the data
printf("\nName: %s", ArrayPointer[index++]);
ArrayPointer[index++] would, as it is defined in the parameter list, return an int. How is that supposed to store a name ? It will store an integer!
Once again, that said, you can't call that Function (pun intended) with that particular argument. Let's view your types:
int Data1[] = {10,10};
int Data2[] = {20,20};
int Data3[] = {30,30};
int *NameList[] = {Data1, Data2, Data3};
Data1 Data2 Data3 NameList
int[2] int[2] int[2] int*[3]
Contrary to what you said, NameList is not a pointer to an array of arrays. I feel i need to show you what that would be:
int (*NameList)[N][M] = Some3DimensionalArray;
That wouldn't make sense at all. So what do you have?
Data1 = array of 2 int
Data2 = array of 2 int
Data3 = array of 2 int
NameList = array of poiners to int
That is what you got. And you pass NameList to a Function that wants a pointer to an int. It must fail already at the time you call Function in main! I've got no idea what you mean by name in that line in Function. But if you want to print out the integers that are stored in the arrays pointed to (by pointers to their first element), you can do it like this (keeping your code as much as i can):
// don't forget the return type, mate. Also see below
void Function(int **ArrayPointer)
{
int i, j, index=0;
for (i=0; i < 3; i++)
{
for (j=0; j < 2; j++)
{
// It does not print the data. It is not a string,
// but an int!
printf("\nName: %d\n", ArrayPointer[i][index++]);
}
index=0; //Counter reset to 0
// no need to increment the pointer. that's what the indexing by i
// above does
// ArrayPointer++;
}
}
I keep preaching people asking questions the difference between a pointer and an array. It's crucial to write correct code. I hope i could help. At the end, just a little though about the difference between int[] and int*. The first is an incomplete array type, while the second is a complete type (pointer to int):
typedef int Single[]; // array of indeterminate size.
typedef int *Pointer; // pointer to int
Single s1 = { 1, 2, 3, 4 }; // works!
Pointer s2 = { 1, 2, 3, 4 }; // no no, doesn't work. s2 wants an address
s2's type now has a type different from int[], because you initialized the array which would have incomplete type, the array s1 become complete after defined. It has type of int[4]. In parameter lists, however, there exist a special rule, which will cause any array type (even complete ones!) to be equivalent to a pointer to their first argument. Thus:
void f(int *a) <=> void f(int a[]) <=> void f(int a[42]);
void f(int (*a)[42]) <=> void f(int a[][42]) <=> void f(int a[13][42])
// ...
That's because you can't pass arrays by value. The compiler abuses that to make array types equivalent to pointers to their first element. Same deal with functions:
void f(int a()) <=> void f(int (*a)())
Because you can't pass functions by value (huh, doesn't even make sense at all to me), the compiler abuses it to make a function type in a parameter list equivalent to a pointer to that function type.
int Data1[]
has the type of
int *
and
int *NameList[]
has the type of
int **
You have a two-dimensional array there. Most likely you meant:
Function(int **ArrayPointer)
On that note, ANSI C/C89/C99 functions have an explicit return type (or void), e.g.
int main() { ... }
void Function() { ... }
The value pointed to by ArrayPointer is an int, not a string. Thus
printf("\nName: %s", ArrayPointer[index++]);
Should be written as something else.
A third thing: index == j in your code. Thus index can be removed in favor of j.
i and j are probably not good variable names here because ArrayPointer is not name describing a list of something.
If you need more help, please post what you're looking to do, because you code has several bugs (and oddities) in it.
Judging by your "answer" (you really should have edited your original post and added this information), you probably want something like this:
void draw_all_sprites(Sprite *sprites, size_t num_sprites)
{
Sprite *cur_sprite;
size_t i;
for(i = 0; i < num_sprites; ++i)
{
draw_sprite(cur_sprite);
++cur_sprite;
}
}
A fairly simple for loop to iterate through elements in an array.
Paramod,
is there a function you need to call that takes something along the lines of
void drawSprite(int *data, int rows, int cols)
?
Then you need to have all data in a single chunk of memory. In your example, the compiler allocates a separate chunk for every row, and then another chunk to hold the three pointers to rows. Thus, the array is kept in 4 different places.
What you need is a multidimensional array rather than array of arrays. Initialize your data like this:
int data[3,2] = {{10,10},{20,20},{30,30}};
Then you can call your function like this:
drawSprite(&data[0,0], 3, 2);
Using multidimensional array places all elements in one block of memory. The advantage is, you can pass the piointer to first element, and you know where all other elements are. The disadvantage - all rows are allocated the same size.
I made some corrections in your program please find them and compare. I know its too late for the response. But I saw this today itself.
int Data1[] = {10,10};
int Data2[] = {20,20};
int Data3[] = {30,30};
int *NameList[] = {Data1, Data2, Data3};
main()
{
Function(NameList);
}
Function(int *ArrayPointer)
{
int i, j, index=0;
for (i=0; i < 3; i++)
{
for (j=0; j < 5; j++)
{
//It does not print the data
printf("\nName: %d\n", *((int *)ArrayPointer[i] + index));
index++;
}
index=0; //Counter reset to 0
}
}
Explanation:
When you pass NameList to Function as a pointer to an integer, what gets passed is the address of the first element of the array, which happens to be Data1 (an address to an array). But since this address is held in an array of ints, it will be considered as an integer. To make it behave like an address to an array(or, for that matter pointer to an int) you need to cast it to (int *). Thats what I did in :
printf("\nName: %d\n", *((int *)ArrayPointer[i] + index));