|
Just mask the bits[^] out
(do you still need some help ?)
They sought it with thimbles, they sought it with care;
They pursued it with forks and hope;
They threatened its life with a railway-share;
They charmed it with smiles and soap.
|
|
|
|
|
I want to use a pointer to get an array elements value.
char s1 = {1,2,3,4,5,6,7};
int t1 = *(int*)(&s1[2]);
I think t1 value is 3456,but in fact, it returns a strange value looks like an address value.
But I make a struct type like:
struct TestStruct {
char c1;
char c2;
char c3;
char c4;
}ts1;
ts1 = *(TestSTruct*)(&s1[2]);
then I can get ts1.c1 = 3, ts1.c2 = 4, ts1.c3 = 5,..
Can anybody give me some hint?
modified 13-Dec-13 2:19am.
|
|
|
|
|
|
In both cases your syntax seems to be somewhat confused. For case 1 why not just:
char s1[] = {1,2,3,4,5,6,7};
int t1 = s1[2];
In case 2, you are casting an array to a structure which will in many cases break your code. Structures will often have their elements aligned on word boundaries so what you think is elemnt n of the array is actually something completely different. If you want to use a structure then fill it with your data in the first place. Don't use casts unless you know that the data will be in the locations you think it will.
[edit]
Added [] after s1 , as Stefan pointed out.
[/edit]
Veni, vidi, abiit domum
modified 13-Dec-13 5:00am.
|
|
|
|
|
shouldn't this be
char* s1 = {...};
rather than
char s1 = {...};
?
The latter is just a single char, and using s1 as an array will lead to invalid memory references; most likely such attempts will access arbitrary adresses on the stack (i. e. other stack variables or parts of them).
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|
|
Forgot to indicate, s1 is a global array.
In fact, I tested, the method works, the weird value is because I use %d to print, when i change %d to %x, it prints correct result
|
|
|
|
|
My point was that the code you posted produces a compiler error in line 1. I suggested you should correct it in your posting so we can see what you your code really looks like, rather than guessing what it might be.
The difference between %d and %x is that the former expects a signed integer variable and prints it as such, whereas the latter will completely ignore the type of the variable and print whatever it finds in unsigned hexadecimal. In general, I doubt that is what you wanted, although for values lower than 10 it may look like it. If %d produces a different output than %x for a variable of type char , then the only relevant difference is signed/unsigned, so %ud shoud print the same as %x .
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|
|
econy wrote: then I can get ts1.c1 = 3, ts1.c2 = 4, ts1.c3 = 5,..
Note that there is no guarantee the compiler will lay out struct members in the exact same order you defined them.
econy wrote: ts1 = *(TestSTruct*)(&s1[2]);
There is no guarantee this will work as expected with any modern compiler, especially if that struct contains more than just four char s. The compiler may have to modify the total memory layout depending on padding, virtual function table, base classes, and debug information (and possibly for other reasons, too).
If you want a clean solution, just provide a simple constructor and maybe assignment operator:
struct TestStruct {
TestStruct(const char c1_, const char c2_, const char c3_, const char c4_)
: c1(c1_), c2(c2_), c3(c3_), c4(c4_)
{
}
TestStruct(const char* s)
{
operator=(*s);
}
TestStruct* operator=(const char* s)
{
if (s != nullptr)
{
c1 = c1_;
c2 = c2_;
c3 = c3_;
c4 = c4_;
}
return *this;
}
...
};
You can then initialize your structs in any of the following ways:
const char* s1 = {1, 2, 3, 4, 5, 6, 7};
struct TestStruct ts1(3, 4, 5, 6);
struct TestStruct ts2(s1+2);
struct TestStruct ts3;
ts3 = s1+2;
Please note that this last assignment may lead to unintentional errors if used carelessly. but at least it's readable and extendable.
[edit]
Sorry, I just noted that you asked about C, not C++. For C, most of my concerns expressed above don't apply! Your assignment statement is essentially correct in that case (although you could simplify &s1[2] to s1+2 if you want to)
[/edit]
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
modified 13-Dec-13 5:46am.
|
|
|
|
|
Since 64-bit C++ code does not allow inline assembly instructions, how can I execute a jmp instruction when I need to?
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Why would you need to?
Veni, vidi, abiit domum
|
|
|
|
|
Richard MacCutchan wrote: Why would you need to?
I want to transfer control to a different function without disturbing the stack. (Without push ing anything more onto it.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
|
// how can I execute a jmp instruction when I need to?
1. Organize a buffer for the JMP executing
enum {
#ifndef _WIN64
jmpAddrIdx = 2, jmpLen = 10, #else
jmpAddrIdx = 3, jmpLen = 16, #endif
};
static BYTE jmp[jmpLen] = {
#ifdef _WIN64
0x50, 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x48, 0x87, 0x04, 0x24, 0xc3 #else
0x50, 0xb8, 0x00, 0x00, 0x00, 0x00,
0x87, 0x04, 0x24, 0xc3 #endif
};
2. Fill the address part there in (low Bytes first)
memcpy(&jmp[jmpAddrIdx], YOUR_DESIRED_ADDRESS, sizeof(DWORD_PTR));
3. Take the pointer of an existing global function(void) (Long enough: see jmpLen above)
4. Mark the addressed space of the function as writeable
DWORD dwOldMode(0);
if (VirtualProtect(pfnYourShellFcn, jmpLen, PAGE_EXECUTE_READWRITE, &dwOldMode)) {
5. Write the jump into the function
memcpy(pfnOriginal, jmp, jmpLen);
6. Mark the space as original
VirtualProtect(pfnYourShellFcn, jmpLen, dwOldMode, &dwOldMode);
7. Call the pointed function
(*pfnYourShellFcn)()
8. Be thrilled.
They sought it with thimbles, they sought it with care;
They pursued it with forks and hope;
They threatened its life with a railway-share;
They charmed it with smiles and soap.
modified 13-Dec-13 7:25am.
|
|
|
|
|
That's a great answer. Thanks!
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
I'm thrilled.
Veni, vidi, vici.
|
|
|
|
|
|
I did think of that, however I don't know if it works across functions.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Hey hi to all.....I am looking for some basic C tutorials for gaining C language knowledge.
Thanks.
|
|
|
|
|
A Google search[^] finds you plenty. Although your time may be better spent learning C++, or even C#. It is largely a question of what area of development you plan to work in.
Veni, vidi, abiit domum
|
|
|
|
|
A android-phone connect to PC by USB line, I hope to get the nowtime screen picture and show it on the dialog. Are there any ideas to do this??
Now, I get "dev/fb0" file(by "adb push /dev/graphics/fb0"), how should I do to convert to an image?
If my way is wrong, please tell me how to do this??
This is my first question on the Codeproject, please help me !!
|
|
|
|
|
|
Hi,
I am using MFC. I want to draw a color filled object (for example, circle) to show on the top of everything else?
Best,
|
|
|
|
|
this will draw a circle on top of everything:
HDC hdcDesktop = GetDC(NULL);
Ellipse(hdcDesktop, 100, 100, 200, 200);
|
|
|
|
|
Look up GDI (or GDI+), it is the simple MS way of drawing things. Usually works pretty efficiently too so if you learn it enough, you'll figure out the tricks to doing high-speed graphics. Making complex object in GDI can be a pain though, so there are other graphics libraries for more complex objects. You can however, build up on GDI and make complex objects.
|
|
|
|
|
I am using Visual Studio 2010 Pro, and have a unique issue that I'm hoping someone can help with. I overloaded the move operator = on a class, with the following code:
template<class T>
MyClass<T> &MyClass<T>::operator =(MyClass &&other) {
if (this != &other) {
std::swap(m_Data , other.m_Data ); std::swap(m_Size1, other.m_Size1); std::swap(m_Size2, other.m_Size2); std::swap(m_Size3, other.m_Size3); std::swap(m_Bool1, other.m_Bool1); std::swap(m_Bool2, other.m_Bool2); }
return *this;
}
When I enter this method in the debugger, all of the fields of both *this and other are what I expect. In case it matters, the values are:
*this other
m_Data 0 0x15E4D2EC0
m_Size1 0 5041
m_Size2 0 5041
m_Size3 0 1
m_Bool1 true false
m_Bool2 true true
My expectation is that the calls to std::swap exchange the values of all the aforementioned fields. However, on the first call to swap, when I step into the function, I get that _Left = 0 and _Right = 0x7FEF5B07EDF. WTF? Why did the value of _Right change from 0x15E4D2EC0? Even more confusing, is that at the end of the function, _Left = 0x7FEF5B07EDF, _Right = 0, but upon returning, the value of other.m_Data has NOT changed to 0. Additionally, the following fields in the "other" object changed to the values indicated (after only executing the first std::swap):
other
m_Data 0x7FEF5B07EDF (should be 0)
m_Size1 67251472 (should be 5041)
m_Size2 0 (should be 5041)
m_Size3 67257296 (should be 1)
m_Bool1 true (should be false)
m_Bool2 true (should be true) WTF? Why does calling std::swap on a single field totally hose my entire object? It is as if the first call somehow changed the type of other. Can anyone shed some light onto what is happening here? Additionally, when the future calls of std::swap are executed (all but the first), they copy the value from other to *this, but don't change the value of other (for example, after executing std::swap(m_Size1, other.m_Size1), I would expect m_Size1 = 67251472 (which it does), and other.m_Size1 = 0 (it is still equal to 67251472). Thanks,
Sounds like somebody's got a case of the Mondays
-Jeff
modified 11-Dec-13 14:35pm.
|
|
|
|
|