|
|
1>ModifyDlg.obj : error LNK2001: 无法解析的外部符号 "public: virtual int __thiscall CModifyDlg::OnInitDialog(void)" (?OnInitDialog@CModifyDlg@@UAEHXZ)
1>WorkDlg.obj : error LNK2001: 无法解析的外部符号 "protected: virtual int __thiscall CWorkDlg::OnInitDialog(void)" (?OnInitDialog@CWorkDlg@@MAEHXZ)
|
|
|
|
|
|
Here's what i have tried.
#include <iostream>
#include <cstring>
#define MAX 100
using namespace std;
int m=0;
class Names{
char name[5][30];
public:
void getdata(){
cout<<"Entre name :\t";
cin.ignore(1000, '\n');
cin>>name[m];
m++;
}
void display(void){
for(int i=0; i<m; i++){
cout<<name[i]<<endl;
}
}
};
int main(){
Names x;
for(int i=0; i<5; i++){
x.getdata();
}
x.display();
return 0;
}
i tried getline(), but it was giving error. How do i take a string as a input ?
modified 10-Mar-18 0:37am.
|
|
|
|
|
Please test it and let me know whether it solved your requirement.
#include <iostream>
#include <string>
#define MAX 100
using namespace std;
class Names {
string name[3];
public:
void getdata()
{
for (int i = 0; i < 3; i++)
{
cout << "Enter Names:" << endl;
getline(cin,name[i]);
}
}
void display(void) {
for (int i = 0; i<3; i++) {
cout << name[i] << endl;
}
}
};
void main()
{
Names n;
n.getdata();
n.display();
getchar();
}
|
|
|
|
|
Tarun Jha wrote:
i tried getline(), but it was giving error. Can you make your font size larger? I cannot see the error from here.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
i will try .
and thank you
|
|
|
|
|
I am working with an ARM microcontroller and I have kind of a statemachine with several hundred states. In order to be able to overview it, I have written the code so that it has a 1:1 correspondence with a flowchart specification. I have removed irrelevant code, but basically the code works like this:
Bool_t (*returnTrueOrFalseFunctionPtr) (void);
void (*actionFunctionPtr) (int);
struct myStruct_s {
returnTrueOrFalseFunctionPtr trueOrFalse;
struct myStruct_s* whereToGoIfTrue;
struct myStruct_s* whereToGoIfFalse;
actionFunctionPtr actionsToPerformInThisState[5];
int actionArguments[5];
};
static struct myStruct_s myStateMachine1[];
static struct myStruct_s myStateMachine2[];
static struct myStruct_s myStateMachine3[];
static struct myStruct_s myStateMachine4[];
define myStateMachine1 ms1
define myStateMachine2 ms2
define myStateMachine3 ms3
define myStateMachine4 ms4
static struct myStruct_s myStateMachine1[] = {
{evaluateSomething, &ms1[1], &ms1[3], {startMotor,increaseSpeed, NULL, NULL, NULL, 3,5, 0, 0,0},
{evaluateSomething, &ms1[2], &ms2[0], {stopMotor, openExhaust, decreaseSpeed,NULL, NULL, 1,20,13,0,0},
{evaluateSomething, &ms1[0], &ms1[2], {openRelay, writeStatusToLog,increaseSpeed,NULL, NULL, 4,5, 87,0,0},
{evaluateSomething, &ms1[4], &ms2[1], {blah blah blah... },
{evaluateSomething, &ms2[1], &ms2[2], {blah blah blah... },
};
struct myStruct_s myStateMachine2[] = {
{evaluateSomething, &ms2[1], &ms2[3], { blah blah blah... },
{evaluateSomething, &ms2[2], &ms3[0], { blah blah blah... },
{evaluateSomething, &ms3[1], &ms3[3], { blah blah blah... },
{evaluateSomething, &ms2[4], &ms4[1], { blah blah blah... },
{evaluateSomething, &ms4[0], &ms2[2], { blah blah blah... },
};
I am very happy with this code format, it make it very easy for me to follow where I am in the statemachine/flowchart and decide where to go next. My problem is that I need to port this code to a microcontroller that has little memory, so I would like to memory-optimize the code heavily. I have already replaced my action function pointers with an enum instead:
enum actionsToPerformInThisState_e {
startMotor_,
stopMotor_,
openRelay_,
openExhaust_,
writeStatusToLog_,
decreaseSpeed_,
increaseSpeed_,
NULL_
};
struct myStruct_s {
returnTrueOrFalseFunctionPtr trueOrFalse;
struct myStruct_s* whereToGoIfTrue;
struct myStruct_s* whereToGoIfFalse;
actionsToPerformInThisState_e actionToPerformInThisState0 : 3;
actionsToPerformInThisState_e actionToPerformInThisState1 : 3;
actionsToPerformInThisState_e actionToPerformInThisState2 : 3;
actionsToPerformInThisState_e actionToPerformInThisState3 : 3;
actionsToPerformInThisState_e actionToPerformInThisState4 : 3;
int actionArguments[5];
};
What else can I do to reduce memory usage? Since most states don't use all 5 actions, I would like to have variable number of actions, but the elements in the array must be of same size, or can anybody think of a workaround (I can't place the actions outside the array and have a pointer to them because then the nice readability is lost). What about all pointers (each occupy a whopping 4 bytes!!!) to next states, can anybody think of another way to accomplish this linking? Other suggestions?
-- modified 9-Mar-18 15:17pm.
|
|
|
|
|
Can the actionArguments have a narrower type? Maybe 5 chars instead of 5 ints?
The next-state pointers could be integers that index into the array of states instead of direct pointers, that would probably allow them to be uint16_t.
Maybe the pointer to the true/false function can be an enum too?
|
|
|
|
|
harold aptroot wrote:
Can the actionArguments have a narrower type? Maybe 5 chars instead of 5 ints?
No, actionArguments can sometimes use 32 bits.
harold aptroot wrote:
The next-state pointers could be integers that index into the array of states instead of direct pointers, that would probably allow them to be uint16_t.
But how would I index when the pointer is pointing to a different array?
harold aptroot wrote:
Maybe the pointer to the true/false function can be an enum too?
Yes, of course, why didn't I think of that!
|
|
|
|
|
arnold_w wrote: actionArguments can sometimes use 32 bits. OK. How often is that needed? Perhaps you can cheat a bit: allow only a couple of 32bit arguments, and the rest must be small. Then if one "block" of actions does need more 32bit arguments, it can be "split" into two successive states (which costs a lot of space, but if splitting is rare then it can be an overall win)
Or maybe: pack arguments in VLQ, but reserve a fixed amount of space. When it doesn't fit, split the state.
The next-state pointers could be integers that index into the array of states instead of direct pointers, that would probably allow them to be uint16_t.
But how would I index when the pointer is pointing to a different array? OK maybe pack together two parts, some bits that indicate which array to look into, and some bits to indicate the index.
|
|
|
|
|
You can tighten the structure at the cost of a carry an action size count. However it does allow you to use the same actions blocks for multiple states. That may often happen in that you just have things like confirm yes/no actions.
I also changed your pointer definitions to const as you are clearly going to have static tables and it will save compiler type casting errors.
I assume you are going to do this .. see the C11 initializers at code end which uses the standard _countof to autosize the arrays.
on GCC it's ARRAY_SIZE() but I hate the name so always define it _countof same as MSVC because it reflects better what it is IMHO.
typedef bool (*returnTrueOrFalseFunctionPtr) (void);
typedef void (*actionFunctionPtr) (int);
struct myAction_s {
const actionFunctionPtr actionToPerformInThisState;
const uint32_t actionArgument;
};
struct myStruct_s {
returnTrueOrFalseFunctionPtr trueOrFalse;
const struct myStruct_s* whereToGoIfTrue;
const struct myStruct_s* whereToGoIfFalse;
const uint8_t maxActionsInThisState;
const struct myAction_s* actionsListInThisState;
};
static void SomeYesFunc (int) {
}
static void SomeNoFunc(int) {
}
static void SomePerhapsFunc(int) {
}
static bool truefalseFunc(void) {
return true;
}
const struct myAction_s yesNoBlock[2] = { &SomeYesFunc, 1 , &SomeNoFunc, 2 };
const struct myAction_s yesNoPerhapsBlock[3] = { &SomeYesFunc, 1 , &SomeNoFunc, 2, &SomePerhapsFunc, 3};
const struct myStruct_s nullState = { 0, 0, 0, 0, 0};
const struct myStruct_s yesNoState = { &truefalseFunc, &nullState , &nullState, _countof(yesNoBlock), &yesNoBlock[0] };
const struct myStruct_s yesNoPerhapsState = { &truefalseFunc, &nullState , &nullState, _countof(yesNoPerhapsBlock), &yesNoPerhapsBlock[0] };
In vino veritas
modified 9-Mar-18 21:53pm.
|
|
|
|
|
Hi
In my mfc application i created a window with multiple tabs as follows:
class MainWind: public CTabView
{
void OnCreate(LPCREATESTRUCT lpstruct)
{
if (CTabView::OnCreate(lpCreateStruct) == -1)
return -1;
AddView(RUNTIME_CLASS(CView1), _T("Sheet1"));
}
}
class CView1 : public CScrollView
{
CView1()
{
}
void LoadData()
{
}
}
A window is created with one tab and CView1 is the view class for my window.
After AddView() i want to call LoadData() function which is available in CView1 class. May i know how to get the object of CView1 class in my MainWindclass.
|
|
|
|
|
|
No. I am unable to get that View object. Any other way?
|
|
|
|
|
Then use the index returned by AddView.
|
|
|
|
|
|
I will get the index of view, but how to access that view using index.? I dint find any function like GetView(index) or something similar to it..
|
|
|
|
|
Sampath579 wrote: I will get the index of view, but how to access that view using index.? I dint find any function like GetView(index) or something similar to it..
You could try calling CTabView::SetActiveView followed by CTabView::GetActiveView
|
|
|
|
|
Each call to AddView returns an index of the tab view. So when you want to make a particular view active you just call SetActiveView passing the relevant index value.
|
|
|
|
|
In my application, i am using a ocx. I created an object to one of the interface in the ocx and called a function on that interface from my application. The return type is LPDispatch data. once i call that function, the memory of my exe is increasing since some memory is creating in that function may be.
Now my question is how to release that memory once my work is done with LPDispatch data. i called release() but it dint help me.
Can some one help me in deleting the memory in my application created by that function in ocx.?
|
|
|
|
|
You should show us the basic code (how you get the interface pointers). In general, you have to call Release() for each kind of interface object when not used anymore. This applies to all pointers retrieved by calling for example CoCreateInstance and QueryInterface .
If a called function is allocating memory internally and returning that to the caller it should be documented. The documentation should then include how to free the memory (e.g. with CoTaskMemFree ).
|
|
|
|
|
Thanks. Please find the code
VARIANT Attributessets;
VariantInit(&Attributessets);
m_OcxObj->GetAttributes(ID, &Attributessets);
Attributessets.pdispVal->Release()
|
|
|
|
|
How did you know that the memory is not released and how do you determine the memory used by your application?
You have to know how the memory is managed which requires knowing the used allocation method. Most memory is allocated in the default per-process heap. If this heap is used up, it is resized by requesting more memory from the operating system. But it will not shrink (at least not immediately) when freeing memory (which occurs when the reference count reaches zero upon releasing). It is finally returned to the operating system when the process terminates. As a result, you might see increasing process memory usage while the process is running.
There is a rather old article that explains the heap managment for Windows: Heap: Pleasures and Pains[^].
In your case of a VARIANT set by a OCX function you have no control over the memory management and even did not know which allocation method is used. If an object must be released depends on the data stored in the VARIANT and should be part of the documentation. In your case of a pdispVal , the OCX control might for example increase the reference count for the dispatch when calling GetAttributes() . Then it will be released finally when releasing the OCX control or you have to call Release() which should be again mentioned in the documentation. It depends also on what you are doing with the interface. If you are calling dispatch functions that increase the reference count, you have to call Release() the same times.
|
|
|
|
|
Thanks for the information provided.
For the question:
How did you know that the memory is not released and how do you determine the memory used by your application?
we call this Getattributes() method in a for loop. for every iteration, it takes around 8 KB memory and finally at the end of this loop process memory shoots up by 50 MB,which is unwanted for us.
we did call Release()method on the pDispval once. but did not work..
i will once again explain the worflow and my questions to give more clarification..
First we get the attributes from the OCX interface using GetAttributes() and we get variant with Pdispvalue.... Does OCX increase the refernce count of Pdispvalue to one here ?
Then we attach this pdispval to the OledispatchdriverObject using AttachDispatch()...Does the refrence count go to two ?
OCX gets destroyed only when main application ends but increase in the memory effects our application.
Do i need to call Release() twice on the pDispval to make it clear ? Does memory gets freed at the end of second Release() call or is it the OCX destruction that clears it.
|
|
|
|
|