|
The arithmetic for void* is not defined, so if you need pointer arithmetic you must do it with a type other than void*. However, the void* is guaranteed to be capable of holding any address on the machine, while other types of pointers do not guarantee it. But, for practical purposes on practical platforms with practical processors you may consider that all pointers are interchangeable.
This means that your code should be re-written to:
int i[10];
void* p = i;
int j = * (((int*)p)+1);
In other words: first cast the void* to int*. On practical systems this conversion does not produce any machine instructions, so it is not really executable code. This means that performance is not an issue.
After the cast the compiler treats the pointer as an int*, so the "+1" arithmetic is well defined (equivalent to "++"). It will be, in fact, equivalent to advancing the pointer to the address where the next int lies. In Win32 this will be an increment of 4 bytes. I've seen SOLARIS implementations where this same code would produce an increment of 8 bytes, to correctly handle its 8 byte int's.
The code I wrote is perfectly legal ANSI, compiles and runs correctly on all platforms, and I wouldn't consider it ugly. Your original code too, except that the precedence is not correct (you increment while the pointer is still void* and at that point it has no arithmetic logic).
Anyway, the second piece of code you propose should not compile. But that can be easilly fixed with "+1" instead of "++". But your reasoning changed in the second example, since you forced the cast from void* (that has no arithmetic logic) to char* (that has arithmetic logic) before incrementing, and so the increment is well defined. However, the increment amount is not correct, because sizeof(char) is 1 and not 4. The char*++ points to the next character (1 byte), instead of the next int (4 bytes). That should have resulted in a bad value for j. Didn't it?
Anyway, below is a piece of code you can test. I initialized "i" to show you that "j" gets a bad value (after fixing from "++" to "+1"). Also, you can see that "k" and "m" get the correct value. As a final note, the code for all 3 integers "j", "k", and "m" as the same instruction type and count, and their efficiency is the same. Of course "j" is wrong, but the compiler doesn't know that (however, some processors may generate exceptions when integers are not aligned, which may result in crashes or slow operating system exception handling).
The "ip" and "n" are not as efficient as the cast versions of "j", "k", and "m" in the debug version. In the release version they should be much more efficient, but the use of the "ip" is most adequate to situations where performance is not an issue, or you intend to do multiple accesses and manipulate the address of the pointer often, or you want the code to be clear. The manipulation could also be done with incrementing indexes in the "m" example, of course.
#include <stdio.h>
void main(void) {
int i[10]={ 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010 };
void* p = i;
int j = *((int*) (((char*)(p))+1) ); // Ugly
int k = *(((int*)p)+1); // Pretty
int m = ((int*)p)[1]; // Also pretty
int* ip=(int*)p;
int n = *++ip; // Even prettier
printf("j=%d, k=%d, m=%d, n=%d\n", j, k, m, n);
}
Rilhas
|
|
|
|
|
hi,
how will you display an icon on a button(CButton MFC VS2005 ), the icon is in say a fil c:\something.ico
|
|
|
|
|
First u have to load the icon using LoadImage( ) function.. then u will get a handle(HICON) for the icon. Now Pass this handle in the SetIcon function of the CButton
nave
|
|
|
|
|
HICON hicon=(HICON)LoadImage(
AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDR_AnswerTYPE),IMAGE_ICON, 48, 48, LR_DEFAULTSIZE);
m_Button1.SetIcon(hicon);
and you need to set icon in property window from your button to true.
|
|
|
|
|
thankx a lot guys. Problem solved.
Appreciate the help
|
|
|
|
|
how comparing similar images to determine how they differ and by how much.? any idea?any code please?
|
|
|
|
|
This is infact not a simple question. I can provide you with hint that try to make Gaussian modal of both images and then compare them. So try to study Gaussian modal first. I hope it helps.
Good luck
We Believe in Excellence
www.aqueelmirza.cjb.net
|
|
|
|
|
The only reliable general purpose image comparison techniques currently available work at a low level. For example, imagine image 1 is a picture of you, and image 2 is a picture of you holding a red ball.
Current gneral purpose comparison techniques don't try to understand that both images contain the same person, and that they are diferent because there is a ball in the second one. Intead, the most reliable techniques today start by subtracting both images and detecting which portions result in a non-zero value. These techniques are the basis for video compression today.
So, your question is not specific enough. What diferences do you which to detect? If you are trying to determine what is diferent in the "meaning" of the pictures then good luck! It is an active area for research, and there is no general solution for it on the horizon. For specific solutions (like detecting that in one image the person has the eyes open and in the next the eyes are closed, or that a room is empty in one picture and not empty in the next) solutions already exist in various domains.
If you intend to determine changes at a lower level then several techniques exist. But be prepared for a very computationally intensive topic, so get yourself a fast processor and be prepared to use C/C++ or even some assembly language!
Rilhas
|
|
|
|
|
im looking for a place where i can find a list/guide of the microsoft standards for a GUI eg how many DU's between radio button etc
thanks
|
|
|
|
|
|
I have a program which has a total of array size of 94000 float(31 arrays).
When I change 9 of the arrays (73737 size) into double, my program seems not working.
Is the total array size too big ?
How to fix the problem ?
Thanks for any help.
|
|
|
|
|
Typically, when you need an array of more than a few hundred elements, it is best to allocate the array on the heap. This allows you to create arrays bounded only by memory (or 2GB if on w32).
onwards and upwards...
|
|
|
|
|
Thanks for the advice.
You mean I should using pointers ? I am a programer from Fortran/Java. I have not got used to pointers. Give me detailed or further advice please.
|
|
|
|
|
For the array, in order to use the heap memory, you can allocate your array like this
<br />
float* floatArray = NULL;<br />
floatArray = new float[100];<br />
and when you finish using your array, you can
<br />
delete [] floatArray;<br />
floatArray = NULL;<br />
I wish it help!
Nacho
|
|
|
|
|
Thanks Nacho. I have implemented your code suggestion.
|
|
|
|
|
Thanks for the advice.
You mean I should using pointers ? I am a programer from Fortran/Java. I have not got used to pointers. Give me detailed or further advice please.
I particularly use six big arrays a[8200],b[8200],c[8200]
Ideally I need to expand my program to a[16400],b[16400],c[16400]. However, I tried these expansion, the program stopped to work. message says: memery problem.
-- modified at 15:27 Monday 24th April, 2006
|
|
|
|
|
using pointers will not fix all your problems but will help you deal with memory problems.
normally, when allocating memory on the heap ( with new ) you will have a immediate result telling you that the allocation worked or not.
Maximilien Lincourt
Your Head A Splode - Strong Bad
|
|
|
|
|
Thanks
I need to expand the size of the arrays. How can I do this ?
Ideally I should also use "double" instead of "float" to improve the accuracy of the
calculations. However, I tried I can not do it now due to the memery limitations.
Please help me to get a way to deal with this problem
Thanks
|
|
|
|
|
|
i agree, Use heap instead of stack. If you ar ein C++ now, then you won't be really be able to avoid pointers and dynamic allocation.
|
|
|
|
|
would you please give me some code example segments for using GlobalAlloc()?
Thanks
|
|
|
|
|
mrby123 wrote: would you please give me some code example segments for using GlobalAlloc()?
There's no reason to use GlocalAlloc() , unless you are maintaining old 16-bit code. Use new and delete instead.
"Let us be thankful for the fools. But for them the rest of us could not succeed." - Mark Twain
"We will be known forever by the tracks we leave." - Native American Proverb
|
|
|
|
|
I would strongly sugest you not to use GlobalAlloc(). Why limit your code to Windows if you don't really need to? Standard ANSI should be fine for your problem. I assume, of course, that you are programming for Win32. If this is not the case then my comments don't apply. But if you avoid GlobalAlloc() you can easilly port to LINUX, which is very similar to Win32 but where GlobalAlloc() doesn't exist.
The first thing you need to do is estimate how much memory you are demanding from the system. From your figures I assume the largest is 3 arrays of doubles with 16400 entries each. Since each double is 8 bytes on most platforms, this results in a total of 393600 bytes of RAM. That's peanuts by today's standards... I assume your computer is equipped with 16MB of RAM or more, so memory outage is surelly not the problem. I have 512 MB, and I once needed 1.3 GB for a simulation, and the virtual memory manager tolerated it just fine. So I'm sure memory outage is not a problem.
There are no real limits on array sizes except those you declare on the stack. Stack is the only real limited resource. It is the space where you declare local variables, and the space the compiler uses to remember where to return to after a function call and where it places the parameters that you pass to functions.
If you are not used to pointers then I would suggest you use a little class to wrap the pointer code. I will paste an example below. This will hide the complexities of allocation and will tolerate bad pointer coding practices.
template <class t="">
class Array {
protected:
T* itsBuffer;
long itsBufferCount;
void Crash(void) { char* p=0; *p=0; }
public:
Array(long count) {
itsBuffer=new T[count];
itsBufferCount=count;
if (!itsBuffer) Crash();
}
Array(Array<t>& arr); // dummy
~Array() {
if (itsBuffer) delete [] itsBuffer;
}
long GetCount(void) {
return itsBufferCount;
}
T* Get(long index_0_based=0) {
if (index_0_based<0) Crash();
if (index_0_based>=itsBufferCount) Crash();
return itsBuffer+index_0_based;
}
T& operator[](long index_0_based) {
return *Get(index_0_based);
}
};
long main_2(Array<double> arr) {
return arr.GetCount();
}
long main_3(Array<double>& arr) {
return arr.GetCount();
}
void main(void) {
long i;
long arr_size=16400;
Array<double> arr_a(arr_size);
Array<double> arr_b(arr_size);
Array<double> arr_c(arr_size);
#ifdef _DEBUG
// slow protected implementation to detect software errors
Array<double>& a=arr_a;
Array<double>& b=arr_b;
Array<double>& c=arr_c;
#else
// fast unprotected implementation for release builds
double* a=arr_a.Get();
double* b=arr_b.Get();
double* c=arr_c.Get();
#endif
for(i=0; i<arr_size; i++)="" {
="" a[i]="100000+i;
" b[i]="200000+i;
" c[i]="300000+i;
" }
="" call="" functions
="" main_2(arr_a);
="" main_3(arr_a);
="" check="" protection
="" a[-1]="316.7;
}
The" example="" above="" shows="" you="" how="" to="" declare="" arrays="" of="" doubles.="" the="" code="" is="" reusable,="" so="" could="" as="" easilly="" integers,="" classes,="" or="" structs.="" class="" protected="" against="" "java="" coding="" style",="" meaning="" that="" don't="" have="" worry="" about="" forgetting="" delete="" array.="" destructor="" will="" do="" for="" you.
the="" protection="" fairly="" simple="" in="" this="" example.="" array="" simply="" crash="" if="" something="" gets="" out="" hand.="" although="" a="" real="" application="" would="" probably="" catch="" these="" exceptions,="" i="" just="" software="" keep="" simple.="" however,="" already="" can="" track="" errors="" other="" causes,="" like="" bad="" addresses.
for="" _debug="" define="" cause="" "a",="" "b",="" and="" "c"="" identifiers="" be="" array<double=""> objects, referencing their respective original arrays. Thus, accessing them with "a[i]", "b[i]", or "c[i]" will invoke the operator[] of class Array. This will be slow, since for every access a function will be called, the parameter will be checked, and if all goes well then the reference to the array entry is finally returned to be used.
For example, the last line has an invalid access to array index -1. If you run this code then this line will cause a crash. If you activate the display of the call stack in the VC debugger you can see where the fault was detected, and climb up the stack to find out where the cause is. For the a[-1] the 4th entry of the call stack will show you the error location. This is a very usefull way of tracking down bugs burried inside complex code.
When you build the release version then the _DEBUG define will not be defined, as, as a result, the "a", "b", and "c" will be compiled as pointers to the buffer of doubles for fast direct access. Setting up "a", "b", and "c" by calling Get() is not the most efficient way to set up the pointers, but typically the impact is not relevant and the code is clean and readable. As a downside no checking is performed, and the a[-1] may not be detected. So build the release after the debug has shown that there are no more bugs. If performance is not an issue, then use only the operator[] version.
I tested the code above with array sizes of 10,000,000 (yes, 10 million!!) and it works just fine. Granted my system has 512 MB, but the theoretical 240,000,000 bytes (10,000,000 entries * 8 bytes per entry * 3 arrays) was confirmed by taking a look at the task manager pausing at a breakpoint after array creation (235 MB in total, with the data taking about 228 MB).
Another thing to note: in JAVA references are implicit, but in C/C++ they are not. So, if you called main_2 then a copy of the array would be made. This would require more memory, and a copy of the contents to be created. In main_3 this does not happen, since the array is passed as a reference. In C/C++ don't forget the & when passing a reference.
To protect the code against such mistakes I added the copy constructor to the Array but with no implementation (// dummy line). If I didn't add the dummy copy contructor line then the compiler would feel free to make a flat copy, and that would be a bad copy for the object (which is not flat). I wouldn't notice it except that the code would use up more memory than necessary and eventually crashed (if I got lucky). No warning or error is issued during compilation stage. This is a very bad flaw in C++ design.
Since I don't want to make copies (in this example) I want a way to protect myself against my own mistakes (of forgetting the & in function prototypes). So I state that I have my own copy constructor (with the dummy line), and so the compiler is not allowed to use its own copy contructor, and, instead, will have to use mine.
But since I don't provide an implementation for the copy constructor then the compiler will issue a link error stating that my copy contructor is unresolved. When I see this error I know I have made a mistake somewhere and after finding the bad line (invocation of main_2) I correct it and the error disappears (everything will be ok, I don't provide a copy contructor implementation but my code doesn't need one, so the compiler has no problem with the missing copy constructor).
I hope this helps.
Rilhas
|
|
|
|
|
Using new and delete [] or GlobalAlloc will work but it is operating at an unnecessarily low level. Standard C++ has a container called a vector which will suit your needs and has many advantages including the fact that it automatically frees memory saving you from the burden of remembering to call delete [] .
To use it first include its header file like this:
#include <vector>
Now you can whip up a vector of float s like this:
std::vector<float> YourVectorOfFloats
Now you can use this as before but you don't need to call delete [] and it has lots of member functions that you can use.
For example, you want to expand it? No worries:
YourVectorOfFloats.resize(400);
Unless he has highly specialized needs there is no good reason for a C++ programmer to use new and delete [] or Win32 APIs such as GlobalAlloc to make dynamic arrays - In general it is a mistake to do so.
Steve
|
|
|
|
|
Thanks Steve, I will implement it.
|
|
|
|
|