|
Maybe my previous description is not specific enough. Hope the code below explain more clearly.
int row0 = 0, col0 = 0;
float ***coords;
int Output1(out1[10][2]);
int Output2(out1[20][2], out2[20][2]);
int Output3(out1[30][2], out2[30][2], out3[30][2]);
int Output4(out1[40][2], out2[40][2], out3[40][2], out4[40][2]);
void Function(const int nMode)
{
int row, col;
switch (nMode)
{
case 0: row = 1; col = 10; break;
case 1: row = 2; col = 20; break;
case 2: row = 3; col = 30; break;
case 3: row = 4; col = 40; break;
}
if (row0 != row || col0 != col)
{
coords = new float**[row];
for (int i = 0; i < row; i++) {
coords[i] = new float*[col];
for (int j = 0; j < col; j++)
coords[i][j] = new float[2]; }
row0 = row; col0 = col;
}
switch (nMode)
{
case 0: Output1(coords[0]); break;
case 1: Output2(coords[0], coords[1]); break;
case 2: Output3(coords[0], coords[1], coords[2]); break;
case 3: Output4(coords[0], coords[1], coords[2], coords[3]); break;
}
}
So in this way, I do not need to declare a bunch of static arrays like:
float out1[10][2];
float out2[2][20][2];
float out3[3][30][2];
float out4[4][40][2];
And some of them may even not to be used throughout the process (if nMode sticks to a certain choice by user). Thus I think dynamic allocation will be more efficient. (Although the allocation and deallocation may cost some effort.)
Going back to original subject, my question is "Is it possible that I can use float (**)[2] instead of float*** , since the dimension of the last layer is always 2?"
Thanks.
|
|
|
|
|
I think my previous suggestion was maybe closer to what you want. You seem to be introducing complexity where it is not needed, and I think your allocation of the array contents is incorrect. I must confess that I am having difficulty following the above logic, and still do not quite understand what you are trying to achieve. txtspeak is the realm of 9 year old children, not developers. Christian Graus
|
|
|
|
|
Nevermind. I actually implemented the code above in my project and everything seems working, without memory leak, crash or data problem. I will go deeper to inspect too. Thanks for your reply.
|
|
|
|
|
|
|
Sorry, correct post should be here[^]
|
|
|
|
|
Hi,
I get this error after I imported an old VC6 explorer-extension dll project to VC9. I needed to do it because I have to compile the extension for 64-bit. I didn't get this error in VC6. Anyone knows what that means and how to fix it?There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition.
Blaise Pascal
|
|
|
|
|
Please check your DEF file :
; KOYOCE.def : Declares the module parameters.
LIBRARY "KOYO32.DLL"
EXPORTS
; DllCanUnloadNow @1 PRIVATE
; DllGetClassObject @2 PRIVATE
; DllRegisterServer @3 PRIVATE
; DllUnregisterServer @4 PRIVATE
; DllzenOnGetClassCLSID @5 PRIVATE
DllCanUnloadNow PRIVATE
DllGetClassObject PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
DllzenOnGetClassCLSID PRIVATE virtual void BeHappy() = 0;
|
|
|
|
|
Thanks, that fixed it. There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition.
Blaise Pascal
|
|
|
|
|
Hi,
I made an installer program fiew years ago, that use ShellExecute and spawn functions. It worked for years.
Today, thoses functions don't work anymore on Windows 7, returning an access denied code (-5).
I tried with ShellExecute, ShellExecuteEx, spawn, ShellExecute 'runas' ... nothing.
What is strange is that the same code works when launching NotePad.exe or Regedit.exe, but not my executables !
What should I do ? Do I have to do something whith my launched executables ? Something whith the manifest or something ?
Thanks for your Help,
Nicolas.
|
|
|
|
|
Do your executables require administrative privileges? The access denied error suggests that there is some problem with that. There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition.
Blaise Pascal
|
|
|
|
|
Well, I never set any privileges settings to my executables : they are just standard MFC apps (orinaly made using VC6 and now with VC 2008).
How can I know if my exe requires administrative privileges ? How do I set these (from Windows or in the code) ???
Even if I give all access to the files from windows shell, it doesn't work.modified on Friday, March 12, 2010 10:51 AM
|
|
|
|
|
see if this thread[^] helps you. There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition.
Blaise Pascal
|
|
|
|
|
Hello folks!
I was just wondering, and thought i ask you, maybe some of you have nice ideas. So here's the deal: there is a static function i have to implement, but its declaration/definition has to match a certian predefined "form", i can write the implementation as i see fit but i can't change the number and types of parameters passed. Let's call this function: TheStaticFunction() . This is actually a callback function that gets called regularry while a 3rd party system is doing its processing. Now, if i want to pass some parameters to this method, i have to use some global variable(s), set them before letting the 3rd party processing begin, eg:
int global_parameter_variable;
void TheStaticFunction()
{
... use value of global_parameter_variable as needed ...
}
...
void Do3rdPartProcessing()
{
global_parameter_variable = 123;
Perform3rdPArtyProcessing();
} This aproach works ok as long as i don't want to use multiple threads to do the processing but with different parameters per thread, since there's only one global global_parameter_variable .
So my question is: what could be done to achieve this?
One solution that comes to my mind is having some global object that stores the parameter values associated with thread handles. So when a thread is trying to use the 3rd party method, it stores its own parameter value associated with its own handle in this global object and inside the static method this global object is used to query the parameter value for the current thread. So something like this:
CThreadedParameters globa_parameter_retriever;
void TheStaticFunction()
{
...
int the_parameter = globa_parameter_retriever.GetParameterValueForThread(GetCurrentThreadHandle());
...
}
void Do3rdPartProcessing(int parameter)
{
globa_parameter_retriever.SetParameterValueForThread(GetCurrentThreadHandle(), parameter);
Perform3rdPArtyProcessing();
globa_parameter_retriever.RemoveParameterValueFor(GetCurrentThreadHandle());
} Of course access to the globa_parameter_retriever would be properly synchronized. This method would probably work but you would have to perform a lookup based on the current thread's handle every time TheStaticFunction is called, althorough this is most likely now that much of an overhaul. So does anyone have any other idea or knows any other, simpler method that exists and i just don't know about it? This all is for now only hypothetical so i can't give you any test results. Thanks for your oppinions.> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Sometimes you just have to hate coding to do it well. <
|
|
|
|
|
You can use the follow code:
__declspec( thread ) int tls_i = 1;
in visual c++.
|
|
|
|
|
Thank you, it looks very promising. > The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Sometimes you just have to hate coding to do it well. <
|
|
|
|
|
|
That also looks good, thank you. > The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Sometimes you just have to hate coding to do it well. <
|
|
|
|
|
i've had good luck with this class:
#if !defined (__THREADLOCAL_H__)
#define __THREADLOCAL_H__
#include < list >
class TlsException
{
public:
explicit TlsException (DWORD error) : m_error (error) {}
private:
DWORD m_error;
TlsException ();
};
template < class T > class CISThreadLocal
{
public:
explicit CISThreadLocal () : m_index (::TlsAlloc ())
{
if (m_index == ~0)
{
#ifdef _DEBUG
throw TlsException (GetLastError ());
#endif
}
InitializeCriticalSection(&g_CritSection);
}
~CISThreadLocal ()
{
if (m_index != ~0)
{
::TlsFree (m_index);
}
m_index = 0;
EnterCriticalSection(&g_CritSection);
for (std::list< T *>::iterator it = m_tsdList.begin(); it!=m_tsdList.end(); it++)
{
delete (*it);
}
m_tsdList.clear();
LeaveCriticalSection(&g_CritSection);
DeleteCriticalSection(&g_CritSection);
}
inline T* operator -> ()
{
return GetThreadLocal ();
}
T* GetThreadLocal ()
{
T* tsd = 0;
try
{
if (m_index != ~0)
{
tsd = reinterpret_cast <T*> (::TlsGetValue (m_index));
if (tsd == 0)
{
tsd = new T;
BOOL success = ::TlsSetValue (m_index, tsd);
if (!success)
throw TlsException (::GetLastError ());
EnterCriticalSection(&g_CritSection);
m_tsdList.push_back(tsd);
LeaveCriticalSection(&g_CritSection);
}
}
}
catch (...)
{
tsd = NULL;
}
return tsd;
}
bool HasTLS()
{
T* tsd = 0;
try
{
if (m_index != ~0)
{
tsd = reinterpret_cast <T*> (::TlsGetValue (m_index));
}
}
catch (...)
{
tsd = NULL;
}
return (tsd != 0);
}
void DeleteThreadTLS()
{
try
{
if (m_index != ~0)
{
T* tsd = reinterpret_cast <T*> (::TlsGetValue (m_index));
if (tsd)
{
BOOL success = ::TlsSetValue (m_index, 0);
if (!success)
throw TlsException (::GetLastError ());
EnterCriticalSection(&g_CritSection);
m_tsdList.remove(tsd);
delete tsd;
LeaveCriticalSection(&g_CritSection);
}
}
}
catch (...)
{
}
}
private:
DWORD m_index;
std::list<T *> m_tsdList;
CRITICAL_SECTION g_CritSection;
CISThreadLocal (const CISThreadLocal&);
void operator = (const CISThreadLocal&);
};
the way it works is:
1. define a class that will hold all your thread-safe data:
class CMyThreadSafeData
{
...
int m_foo;
....
};
2. declare and define a single global variable of type CISThreadLocal:
extern CISThreadLocal < CMyThreadSafeData > threadSafeData;
...
CISThreadLocal < CMyThreadSafeData > threadSafeData;
3. whenever you need to access that thread-safe data, do this:
int threadFoo = threadSafeData->m_foo;
|
|
|
|
|
Thank you. > The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Sometimes you just have to hate coding to do it well. <
|
|
|
|
|
Coorect me if I wrong my interpretation: It looks that you have only to pass an input parameter of the threads.
Well, in this case I think that the usual way is not to store the variable into the global memory but pass a pointer to the thread when it is starting. this pointer points to a struct where the new thread can find all the initial values. You have only to wait that the new thread read all the parameters and store they into his local memory, then the caller can continue the flow destroing the objects.
If that parameters can be changed from the main thread during the execution you can then pass to every single thread a set of pointers to these variables. Of course you'll need to allocate an array of variable (one per each thread). Russell
|
|
|
|
|
Thanks for the reply. Either i misunderstand you or you misunderstand me but if i am correct you are not talking about what i meant. I will try to explain with an example:
Let's say you have a 3rd party library that performs some task, you can specify a pointer to a function for this 3rd party library and during its processing the library will call your specified function, for example to report progress. Let's say, this method has to have one parameter, an unsigned char that will change from 0 to 100 (percentage) as the 3rd party advances in the task.
void MyProgress(unsigned char percentage)
{
...
}
...
SetCallBackProcFor3rdPartyLib(MyProgress);
Do3rdPartyLibProcessing();
... Now, what if you would like to give other parameters to your MyProgress method, for example a handle to a control that should display the progress? You can't just do this:
void MyProgress(unsigned char percentage, HWND control)
{
...
} since the lib requires the method to take only one unsigned char parameter and nothing else. So what you can do to have a way for the MyProgress procedure to have access to this information (the handle) is to create a global variable, store this handle in this before you let the lib do the magic, and use this same variable inside MyProgress .
HWND the_control = NULL;
void MyProgress(unsigned char percentage)
{
CString str;
str.Format("%d %%", percentage);
SetWindowText(the_control, str);
}
...
the_control = handle_of_the_control;
SetCallBackProcFor3rdPartyLib(MyProgress);
Do3rdPartyLibProcessing();
... This works, right? But if you have multiple threads all executing Do3rdPartyLibProcessing and all threads having their very own control to display the progress in, you can no longer use the same approach, since the_control exists only once in memory, so every executing thread would use this same memory when trying to store/retrieve their own control's window handle and bang, welcome to chaosland. So my original question is basicly: how to have a "thread level" global variable (so one that is unique per thread and can be accessed everywhere "inside" the thread). As the others said, TLS (Thread-Local Storage) seems to be just the answer for that.
I hope this clears any misunderstandings, sorry if not.> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Sometimes you just have to hate coding to do it well. <
|
|
|
|
|
VC++
Windows XP
Hi,
I have to maintain a large application which sometimes crashes at the end. The cause is probably a buffer overflow somewhere: From time to time a system error message showed up which said that the code segment had been affected. I would like to find the source of the overflow but couldn't figure out where it could be.
It only happens in the release version. I think this is due to the different initialization of debug memory with CD DD and so on. I think it would be easier, when I could run a debug session with heap and stack being initialized in the same way as in the release version. Is there any possibility to get that?
Or is there a tool which can show me e.g.
slice of memory on the heap | origin routine | virtual addr begin | virtual addr end |
pFoo bar 0x00002000 0x20000000
Thank you
Regards
Werner
|
|
|
|
|
You could compile your project without optimization (debug)
and link it with the debug "pdb" information
(These are the project settings)
Secondly,
you could try to restrict the RT reproducing context as possible virtual void BeHappy() = 0;
|
|
|
|
|
Try also to make the following test (may be in a small separate application) :
{
int* pInt = new int[20];
pInt = new int[10];
pInt = new int[30];
pInt = new int[10];
}
...an then pass it to your diagnostic tool virtual void BeHappy() = 0;
|
|
|
|