How to retrieve data from array of pointers or from a struct?

V

Victor

Hi,

I have 2 problems:

First, I want to grep one pattern at a time from the pattern group
below:

unsigned long long i;

unsigned long long *dataPatternPtr[] = {
0xa0a00000000000aaLL,
0xFFFFFFFFFFFFFFFFLL,
0x5555555555555555LL,
0xAAAAAAAAAAAAAAAALL,
0xCCCCCCCCCCCCCCCCLL,
0x3333333333333333LL,
0xEEEEEEEEEEEEEEEELL,
0x7777777777777777LL,
0x0000000000000001LL,
0xFFFFFFFFFFFFFFFELL,
0xABCDEF0123456789LL,
};

unsigned long long seed = *(dataPatternPtr + 2); // This one
works during compile
unsigned long long seed = *(dataPatternPtr + i); // *********
ERROR ****** But why does this one not work?

But when I compiled, I received this kind of error:


/projects/svdc/aurora.validation/work/vhnguyen/aurora_validation/uboot/
examples/zzzmain.c:295: undefined reference to `memcpy'
make[1]: *** [zzzmain] Error 1


Does anyone know why? It seems memcpy is not found in #include files
but what library memcpy should reside in?

Any best practice to store and retrieve data pattern in my case?

2) I also tried to reduce the above problem to use Struct. In this
case, I assume in order to access pattern # 3, then I should do
*(dataPattern[2].pattern), is it right? I can't really verify
because my compiler spits out error about memcpy like in case 1. In
my patterns, I append data with "LL" for double long word.


struct key {
unsigned long long *pattern;
} dataPattern[] = {
0x0000000000000000LL,
0xFFFFFFFFFFFFFFFFLL,
0x5555555555555555LL,
0xAAAAAAAAAAAAAAAALL,
0xCCCCCCCCCCCCCCCCLL,
0x3333333333333333LL,
0xEEEEEEEEEEEEEEEELL,
0x7777777777777777LL,
0x0000000000000001LL,
0xFFFFFFFFFFFFFFFELL,
0xABCDEF0123456789LL
};

Actually I also have another 3rd question indicated below:

int sizeOfStruct = sizeof(struct key); // Here size is 4 bytes
int totalSize = sizeof(dataPattern); //Here sizeof returns
number bytes (44) . Question: Should it return 88 bytes (11 patterns
* 8 bytes each) instead of 44 ?


Thanks,
Victor
 
U

Ulrich Eckhardt

Victor said:
I have 2 problems:

Start two threads, at least in general.
unsigned long long i;

unsigned long long *dataPatternPtr[] = {

This defines an array of pointers to unsigned long longs...
0xa0a00000000000aaLL,
0xFFFFFFFFFFFFFFFFLL,
0x5555555555555555LL,
0xAAAAAAAAAAAAAAAALL,
0xCCCCCCCCCCCCCCCCLL,
0x3333333333333333LL,
0xEEEEEEEEEEEEEEEELL,
0x7777777777777777LL,
0x0000000000000001LL,
0xFFFFFFFFFFFFFFFELL,
0xABCDEF0123456789LL,
};

....while initialising the pointers with long long values. Is that intended?
I guess not, because typically you don't hardcode addresses except in
low-level driver code. Further, do you intend to modify this? If not, then
make it const.
unsigned long long seed = *(dataPatternPtr + 2); // This one
works during compile

This can also be written as ..= dataPatternPtr[2];
However, it features a conversion between an "unsigned long long*" and
an "unsigned long long". You should definitely crank up the warning level
of your compiler, I'm sure it would have told you.
unsigned long long seed = *(dataPatternPtr + i); // *********
ERROR ****** But why does this one not work?

In C89, all declarations of variables have to precede the code. Since 'i' is
not a constant, you are mixing this here which is what the compiler
complains about. Well, at least that's my guess, since you neither provided
full code nor an error message.
/projects/svdc/aurora.validation/work/vhnguyen/aurora_validation/uboot/
examples/zzzmain.c:295: undefined reference to `memcpy'
make[1]: *** [zzzmain] Error 1

Does anyone know why? It seems memcpy is not found in #include files
but what library memcpy should reside in?

#include only adds the necessary declaration, you still need to link the
right libs. In particular with builtin things like memcpy(), this should be
done automatically. Since you seem to be hacking a bootloader, this might
not be completely the case though. Anyway, this is highly dependent on the
actual compiler, so I'd ask questions about its use in a dedicated forum.

Uli
 
P

Pawel Dziepak

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Victor wrote:
unsigned long long seed = *(dataPatternPtr + 2); // This one
works during compile
unsigned long long seed = *(dataPatternPtr + i); // *********
ERROR ****** But why does this one not work?

You are using an array of pointers not an array of long long values.
Don't forget that sizeof(long long) != sizeof(long long*). See below for
more description.
/projects/svdc/aurora.validation/work/vhnguyen/aurora_validation/uboot/
examples/zzzmain.c:295: undefined reference to `memcpy'
make[1]: *** [zzzmain] Error 1


Does anyone know why? It seems memcpy is not found in #include files
but what library memcpy should reside in?

It looks like you are not linking your output binaries with the standard
C library in which memcpy is placed, are you? You for sure changed
default stettings of your compiler/linker thus it's off topic for clc.
struct key {
unsigned long long *pattern;
} dataPattern[] = {
0x0000000000000000LL,
0xFFFFFFFFFFFFFFFFLL,
0x5555555555555555LL,
0xAAAAAAAAAAAAAAAALL,
0xCCCCCCCCCCCCCCCCLL,
0x3333333333333333LL,
0xEEEEEEEEEEEEEEEELL,
0x7777777777777777LL,
0x0000000000000001LL,
0xFFFFFFFFFFFFFFFELL,
0xABCDEF0123456789LL
};

Actually I also have another 3rd question indicated below:

int sizeOfStruct = sizeof(struct key); // Here size is 4 bytes
int totalSize = sizeof(dataPattern); //Here sizeof returns
number bytes (44) . Question: Should it return 88 bytes (11 patterns
* 8 bytes each) instead of 44 ?

Structure key consist of a *pointer* to long long. Despite the fact long
long appears to be 8 bytes on your architecture, you have 4 byte long
pointers. You should use "unsigned long long pattern;" (not a pointer).

Pawel Dziepak
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iEYEARECAAYFAkkWuMYACgkQPFW+cUiIHNpUuACgkiuduCUE8jj/Z0GRra1TAOUi
SacAnjNhBJK3VUtr1NIsCqRW34PVfpV0
=FBnj
-----END PGP SIGNATURE-----
 
B

Ben Bacarisse

Ulrich Eckhardt said:
Victor wrote:

In C89, all declarations of variables have to precede the code.

In C89 // is a syntax error, so I doubt the OP is using C89 (aka C90).
Since 'i' is
not a constant, you are mixing this here which is what the compiler
complains about.

I don't see what is wrong with initialising a variable with a
non-constant expression. I.e. the fact that i is or is not constant
probably has nothing to do with your suspected source of the error.
Anyway, you are quite correct that only full code (or, better, full
code of a cut down example) can resolve this one:
Well, at least that's my guess, since you neither provided
full code nor an error message.
<snip>
 
K

Keith Thompson

Victor said:
I have 2 problems:

First, I want to grep one pattern at a time from the pattern group
below:

unsigned long long i;

unsigned long long *dataPatternPtr[] = {
0xa0a00000000000aaLL, [...]
0xABCDEF0123456789LL,
};

You're declaring an array of pointers to unsigned long long, but
you're initializing the pointers with integer values. This is
actually a constraint violation, and your compiler should have warned
you about it. Your problem is either that you're invoking your
compiler in some non-standard mode that inhibits the warnings, or
getting warnings and not bothering to tell us about them.

What are you actually trying to do? Do you want an array of integers
or an array of pointers?
 
V

Victor

Victor said:
I have 2 problems:
First, I want to grep one pattern at a time from the pattern group
below:
unsigned long long i;
unsigned long long *dataPatternPtr[] = {
    0xa0a00000000000aaLL, [...]
    0xABCDEF0123456789LL,
  };

You're declaring an array of pointers to unsigned long long, but
you're initializing the pointers with integer values.  This is
actually a constraint violation, and your compiler should have warned
you about it.  Your problem is either that you're invoking your
compiler in some non-standard mode that inhibits the warnings, or
getting warnings and not bothering to tell us about them.

What are you actually trying to do?  Do you want an array of integers
or an array of pointers?

--
Keith Thompson (The_Other_Keith) (e-mail address removed)  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

Hi,

I modified my script to use an array of longs instead of array of
pointers to longs:

unsigned long long dataPatternArray[] = {
0xa0a00000000000aaLL,
0xFFFFFFFFFFFFFFFFLL,
0x5555555555555555LL,
0xAAAAAAAAAAAAAAAALL,
0xCCCCCCCCCCCCCCCCLL,
0x3333333333333333LL,
0xEEEEEEEEEEEEEEEELL,
0x7777777777777777LL,
0x0000000000000001LL,
0xFFFFFFFFFFFFFFFELL,
0xABCDEF0123456789LL,
};

Again, I can successfully access my elements via:

dataPatternArray[0]
dataPatternArray[1]
dataPatternArray[2]
....
dataPatternArray[7]

and so on.

However if I use a variable "i" in a "for" loop to access each of
them:

for (i=0; i <= MAX; i++) {
printf("Pattern = %08x\n", (int *)dataPatternArray);
}

Then the above WON'T WORK because of compile error: undefined
reference to `memcpy


However if I simply hardcode value for "i" like in the following, then
it works. Any idea?

for (i=0; i <= MAX; i++) {
i = 7;
printf("Pattern = %08x\n", (int *)dataPatternArray);
}

Bottom line is I need to CYCLE THRU all patterns to retrieve them.
Why doesn't it work?

Thanks,
Victor
 
K

Keith Thompson

Victor said:
Victor said:
I have 2 problems:
First, I want to grep one pattern at a time from the pattern group
below:
unsigned long long i;
unsigned long long *dataPatternPtr[] = {
    0xa0a00000000000aaLL, [...]
    0xABCDEF0123456789LL,
  };

You're declaring an array of pointers to unsigned long long, but
you're initializing the pointers with integer values.  This is
actually a constraint violation, and your compiler should have warned
you about it.  Your problem is either that you're invoking your
compiler in some non-standard mode that inhibits the warnings, or
getting warnings and not bothering to tell us about them.

What are you actually trying to do?  Do you want an array of integers
or an array of pointers?

Please don't quote signatures.
I modified my script to use an array of longs instead of array of
pointers to longs:

It's a program, not a script.
unsigned long long dataPatternArray[] = {
0xa0a00000000000aaLL,
0xFFFFFFFFFFFFFFFFLL,
0x5555555555555555LL,
0xAAAAAAAAAAAAAAAALL,
0xCCCCCCCCCCCCCCCCLL,
0x3333333333333333LL,
0xEEEEEEEEEEEEEEEELL,
0x7777777777777777LL,
0x0000000000000001LL,
0xFFFFFFFFFFFFFFFELL,
0xABCDEF0123456789LL,
};
Ok.

Again, I can successfully access my elements via:

dataPatternArray[0]
dataPatternArray[1]
dataPatternArray[2]
...
dataPatternArray[7]

and so on.

However if I use a variable "i" in a "for" loop to access each of
them:

for (i=0; i <= MAX; i++) {
printf("Pattern = %08x\n", (int *)dataPatternArray);
}


You're taking dataPatternArray, a value of type unsigned long long,
and converting it to int* (pointer to int). This makes no sense.
You're then printing this pointer value using a "%08x" format; "%x" or
"%08x" is for printing a value of type unsigned int, not int*. (And
you're specifying at least 8 digits, but your values are 16 digits.)

Previously, you showed a declaration of i as an unsigned long long.
This isn't wrong, but since i is an index into the array, which has
only a few elements, it would make more sense to declare it as an int.

You're looping from 0 to MAX. What is MAX? If it's the number of
elements in the array, then you're going past the end of the array.
(That's not related to the symptoms you're describing.)

The way to print a value of type unsigned long long in hexadecimal is:

for (i = 0; i < MAX; i++) {
printf("Pattern = %016llx\n", dataPatternArray);
}
Then the above WON'T WORK because of compile error: undefined
reference to `memcpy

You're not explicitly calling memcpy, but it's possible that your
compiler is implicitly calling memcpy to copy the value, perhaps
because the CPU doesn't have a native instruction to copy a 64-bit
value. memcpy is part of the standard library, and most
implementations will link it automatically, so you don't have to do
anything special to make memcpy available -- but apparently either
your implementation doesn't do that, or you're invoking it
incorrectly, or it's configured incorrectly. I don't think you've
told us what compiler you're using, but you should be able to find a
forum that discusses it. Write a complete self-contained program that
illustrates your problem (not the code fragments you've been posting
here) and post it either here or in a support form for your compiler.
We need something we can compile and run ourselves; if you don't know
what the problem is, you don't know what you can safely leave out. We
can help you with any C language issues, but we can't help you with
any problems you're having with your compiler.

[...]
 
M

Martin Ambuhl

Victor said:
However if I use a variable "i" in a "for" loop to access each of
them:

for (i=0; i <= MAX; i++) {
printf("Pattern = %08x\n", (int *)dataPatternArray);
}

Then the above WON'T WORK because of compile error: undefined
reference to `memcpy


I don't believe you. And your code is random nonsense.
However if I simply hardcode value for "i" like in the following, then
it works. Any idea?

for (i=0; i <= MAX; i++) {
i = 7;
printf("Pattern = %08x\n", (int *)dataPatternArray);
}

Bottom line is I need to CYCLE THRU all patterns to retrieve them.
Why doesn't it work?


Because you haven't bothered to learn even the most basic aspects of C.

/* mha: _Please_ post the real code. Your messages are really a mess.
* Your problem is not reproduceable, simply because you have hidden
* your error by snipping it away. Your description of your problem is
* absurd: by "diagnosing" it yourself, you have only fooled yourself.
* If the following compiles and runs, then you are completely wrong
* about what is happening. And your attempt at a printf statement
* looks like random typing. */

#include <stdio.h>

#define MAX (sizeof dataPatternArray/sizeof *dataPatternArray)

int main(void)
{
unsigned long long dataPatternArray[] = {
0xa0a00000000000aaLL,
0xFFFFFFFFFFFFFFFFLL,
0x5555555555555555LL,
0xAAAAAAAAAAAAAAAALL,
0xCCCCCCCCCCCCCCCCLL,
0x3333333333333333LL,
0xEEEEEEEEEEEEEEEELL,
0x7777777777777777LL,
0x0000000000000001LL,
0xFFFFFFFFFFFFFFFELL,
0xABCDEF0123456789LL,
};
size_t i;

/* mha: note that the following has "i < MAX" instead of your "i <=
MAX". Since you have refused to tell us your definition for MAX,
we can only guess. My definition is above.

Note also that the specifier for a unsigned long long in hex is
not "%08x", and (int *)dataPatternArray is just nonsense. If
you really wanted a pointer to print, the specifier is "%p" and
the cast is to (void *) */
for (i = 0; i < MAX; i++)
printf("Address of Pattern = %p, "
"Pattern = %#08llx\n", (void *) &dataPatternArray,
dataPatternArray);
return 0;
}

[output]
Address of Pattern = dff50, Pattern = 0xa0a00000000000aa
Address of Pattern = dff58, Pattern = 0xffffffffffffffff
Address of Pattern = dff60, Pattern = 0x5555555555555555
Address of Pattern = dff68, Pattern = 0xaaaaaaaaaaaaaaaa
Address of Pattern = dff70, Pattern = 0xcccccccccccccccc
Address of Pattern = dff78, Pattern = 0x3333333333333333
Address of Pattern = dff80, Pattern = 0xeeeeeeeeeeeeeeee
Address of Pattern = dff88, Pattern = 0x7777777777777777
Address of Pattern = dff90, Pattern = 0x000001
Address of Pattern = dff98, Pattern = 0xfffffffffffffffe
Address of Pattern = dffa0, Pattern = 0xabcdef0123456789
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top