Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
haveblue
Aug 15, 2005



Toilet Rascal

Thug Bonnet posted:

No, that's what I'm asking! :) I'm just kind of curious, honestly. But how would the program know "where it is" in memory, how large it is, etc. Also, I assume it's not necessarily contiguous..

Each process's address space is identical*, so that information isn't really useful to anything other than the kernel. If such a query existed, it would return identical results for all processes on the computer. A program generally doesn't have or need the ability to know what physical addresses its virtual pages are at, especially because those may change literally from instruction to instruction under a modern virtual memory system.



*Unless ASLR is enabled, but again, that's only the OS's concern.

Adbot
ADBOT LOVES YOU

Thug Bonnet
Sep 22, 2004

anime tits ftw

HB posted:

Each process's address space is identical*, so that information isn't really useful to anything other than the kernel. If such a query existed, it would return identical results for all processes on the computer. A program generally doesn't have or need the ability to know what physical addresses its virtual pages are at, especially because those may change literally from instruction to instruction under a modern virtual memory system.



*Unless ASLR is enabled, but again, that's only the OS's concern.

Identical in what sense?

Entheogen
Aug 30, 2004

by Fragmaster

Thug Bonnet posted:

No, that's what I'm asking! :) I'm just kind of curious, honestly. But how would the program know "where it is" in memory, how large it is, etc. Also, I assume it's not necessarily contiguous..

I believe the OS allocates a chunk of RAM to the program and maps it using virtual memory. That is for program the memory may start at 0x0000 or something but then OS maps it to real memory. I am not quite sure.

I think for C++ programs "how large it is" can grow as the program continues to allocate new memory on heap, so the OS must be adding to its virtual page. I know for java you have to actually set a maximum amount of heap memory you will use, but not for C++.

Thug Bonnet posted:

Identical in what sense?

I think he means that start of program's heap address is like 0x000 (from program's perspective) ( i have no idea what it actually is ), and is the same for all threads that OS is executing.

Entheogen fucked around with this message at 22:32 on Mar 10, 2008

haveblue
Aug 15, 2005



Toilet Rascal

Entheogen posted:

I believe the OS allocates a chunk of RAM to the program and maps it using virtual memory. That is for program the memory may start at 0x0000 or something but then OS maps it to real memory. I am not quite sure.

Pretty much. Null, the stack, the default heap, and the application code all tend to show up at the same (virtual) address for all programs. The locations of loaded libraries are the same for each launched instance of a linked binary (but may be different for other, different programs).

Incidentally, this is what allows buffer overflow exploits to work and be portable- the locations of parts of the process image can be predicted across systems (and it's what ASLR is designed to break).

quote:

I think for C++ programs "how large it is" can grow as the program continues to allocate new memory on heap, so the OS must be adding to its virtual page. I know for java you have to actually set a maximum amount of heap memory you will use, but not for C++.

The largest possible address depends on which system you're on. On Win32 you get 2GB of virtual space; the largest valid pointer value is UINT_MAX/2. On 32-bit OS X and other Unixes you get somewhere between that and 4GB. On a 64-bit architecture the limit is so high it's not worth calculating.

haveblue fucked around with this message at 22:39 on Mar 10, 2008

Scaevolus
Apr 16, 2007

Thug Bonnet posted:

No, that's what I'm asking! :) I'm just kind of curious, honestly. But how would the program know "where it is" in memory, how large it is, etc. Also, I assume it's not necessarily contiguous..

It depends on the OS. On Linux, /proc/<pid>/ contains a lot of this information, with the files maps and smaps being particularly interesting.

Scaevolus
Apr 16, 2007

Thug Bonnet posted:

No, that's what I'm asking! :) I'm just kind of curious, honestly. But how would the program know "where it is" in memory, how large it is, etc. Also, I assume it's not necessarily contiguous..

It depends on the OS. On Linux, /proc/<pid>/ contains a lot of this information, with the files maps and smaps being particularly interesting.

Example /proc/.../maps file:
code:
00400000-0048e000 r-xp 00000000 08:06 704516               /bin/bash
0068e000-00693000 rw-p 0008e000 08:06 704516               /bin/bash
00693000-0071e000 rw-p 00693000 00:00 0                    [heap]
2b5398859000-2b5398874000 r-xp 00000000 08:06 1146887      /lib/ld-2.7.so
2b5398874000-2b5398875000 rw-p 2b5398874000 00:00 0 
2b5398896000-2b5398897000 rw-p 2b5398896000 00:00 0 
2b5398a73000-2b5398a75000 rw-p 0001a000 08:06 1146887      /lib/ld-2.7.so
2b5398a75000-2b5398aab000 r-xp 00000000 08:06 1148901      /lib/libreadline.so.5.2
2b5398aab000-2b5398cab000 ---p 00036000 08:06 1148901      /lib/libreadline.so.5.2
2b5398cab000-2b5398cb3000 rw-p 00036000 08:06 1148901      /lib/libreadline.so.5.2
2b5398cb3000-2b5398cb4000 rw-p 2b5398cb3000 00:00 0 
2b5398cb4000-2b5398cbc000 r-xp 00000000 08:06 1146884      /lib/libhistory.so.5.2
2b5398cbc000-2b5398ebb000 ---p 00008000 08:06 1146884      /lib/libhistory.so.5.2
2b5398ebb000-2b5398ebc000 rw-p 00007000 08:06 1146884      /lib/libhistory.so.5.2
2b5398ebc000-2b5398f0a000 r-xp 00000000 08:06 1148900      /lib/libncurses.so.5.6
2b5398f0a000-2b5399109000 ---p 0004e000 08:06 1148900      /lib/libncurses.so.5.6
2b5399109000-2b5399118000 rw-p 0004d000 08:06 1148900      /lib/libncurses.so.5.6
2b5399118000-2b5399119000 rw-p 2b5399118000 00:00 0 
2b5399119000-2b539911b000 r-xp 00000000 08:06 1146922      /lib/libdl-2.7.so
2b539911b000-2b539931b000 ---p 00002000 08:06 1146922      /lib/libdl-2.7.so
2b539931b000-2b539931d000 rw-p 00002000 08:06 1146922      /lib/libdl-2.7.so
2b539931d000-2b539945a000 r-xp 00000000 08:06 1148905      /lib/libc-2.7.so
2b539945a000-2b539965a000 ---p 0013d000 08:06 1148905      /lib/libc-2.7.so
2b539965a000-2b539965d000 r--p 0013d000 08:06 1148905      /lib/libc-2.7.so
2b539965d000-2b539965f000 rw-p 00140000 08:06 1148905      /lib/libc-2.7.so
2b539965f000-2b5399666000 rw-p 2b539965f000 00:00 0 
2b5399666000-2b5399b79000 r--p 00000000 08:06 1638711      /usr/lib/locale/locale-archive
2b5399b79000-2b5399bae000 r--s 00000000 08:06 1591741      /var/db/nscd/passwd
2b5399bae000-2b5399bf1000 rw-p 2b5399bae000 00:00 0 
7fff1223b000-7fff12250000 rw-p 7ffffffea000 00:00 0        [stack]
7fff123fe000-7fff12400000 r-xp 7fff123fe000 00:00 0        [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0    [vsyscall]

Scaevolus fucked around with this message at 23:10 on Mar 10, 2008

Thug Bonnet
Sep 22, 2004

anime tits ftw

HB posted:

The largest possible address depends on which system you're on. On Win32 you get 2GB of virtual space; the largest valid pointer value is UINT_MAX/2. On 32-bit OS X and other Unixes you get somewhere between that and 4GB. On a 64-bit architecture the limit is so high it's not worth calculating.

Is it possible to know the size at any given time, though? For example would it be possible to just create a memory dump as a program is running? I'm trying to think of a "hello world" of memory dumps, but I'm not sure where to begin.

more falafel please
Feb 26, 2005

forums poster

Thug Bonnet posted:

No, that's what I'm asking! :) I'm just kind of curious, honestly. But how would the program know "where it is" in memory, how large it is, etc. Also, I assume it's not necessarily contiguous..

That depends on the OS. Also, these will be logical addresses, relative to the page table for your application, so they're basically meaningless outside, unless you can run in kernel mode or something.

But yeah, it's not going to be contiguous, you'll have different segments for the actual program code, static data, stack, and the free store.

edit: crap, I missed that page 6 existed, ignore me.

ehnus
Apr 16, 2003

Now you're thinking with portals!
On Windows you can take the address of the __ImageBase symbol which points to the DOS header of the executable. From there you can find the PE header (the offset of which is located at 0x3C + __ImageBase) and parse it according to the PE/COFF format and figure out which sections are there and how large they are. This won't work for dynamically loaded libraries, you'll have to do something similar by finding the modules base address and going from there.

ELF files work similarly, I believe the symbol most commonly used is __executable_start, which you can cast to the ELF header and interpret from there

cronio
Feb 15, 2002
Drifter

Thug Bonnet posted:

Is it possible to know the size at any given time, though? For example would it be possible to just create a memory dump as a program is running? I'm trying to think of a "hello world" of memory dumps, but I'm not sure where to begin.

On Windows you probably want to look at VirtualQuery: http://msdn2.microsoft.com/en-us/library/aa366902(VS.85).aspx

xobofni
Mar 28, 2003
Really stupid question here about pointers in C.

This code runs just fine.
code:
int main ()
{
    char a[] = "hello world";
    a[0] = 'b';
    return 0;
}
This code crashes.
code:
int main ()
{
    char *a = "hello world";
    a[0] = 'b';
    return 0;
}
I thought those declarations were exaclty the same, but apparently they are not. What am I missing here?

haveblue
Aug 15, 2005



Toilet Rascal

xobofni posted:

Really stupid question here about pointers in C.

This code runs just fine.
code:
int main ()
{
    char a[] = "hello world";
    a[0] = 'b';
    return 0;
}
This code crashes.
code:
int main ()
{
    char *a = "hello world";
    a[0] = 'b';
    return 0;
}
I thought those declarations were exaclty the same, but apparently they are not. What am I missing here?

The first code copies the string constant into the variable-sized array a, the second creates a pointer to the string constant before attempting to change it. These compiled-in constants are read-only by default; if you're using GCC there's a flag you can use to allow writing to them.

Alan Greenspan
Jun 17, 2001

xobofni posted:

Really stupid question here about pointers in C.

This code runs just fine.
code:
int main ()
{
    char a[] = "hello world";
    a[0] = 'b';
    return 0;
}
This code crashes.
code:
int main ()
{
    char *a = "hello world";
    a[0] = 'b';
    return 0;
}
I thought those declarations were exaclty the same, but apparently they are not. What am I missing here?

Click me

more falafel please
Feb 26, 2005

forums poster

xobofni posted:

Really stupid question here about pointers in C.

This code runs just fine.
code:
int main ()
{
    char a[] = "hello world";
    a[0] = 'b';
    return 0;
}
This code crashes.
code:
int main ()
{
    char *a = "hello world";
    a[0] = 'b';
    return 0;
}
I thought those declarations were exaclty the same, but apparently they are not. What am I missing here?

There's two issues here, one that addresses your immediate problem and one that will clear some things up for you.

In the first case, what's happening is you're declaring an array of char (actually, an array of 12 chars), and filling it with 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '\0'.

In the second case, you're taking a pointer and assigning it the address of a string literal which the compiler embedded into the executable somewhere. Generally, those string literals are in read-only segments of memory.

The second point is that pointers and arrays are not the same thing: http://c-faq.com/aryptr/

lmao zebong
Nov 25, 2006

NBA All-Injury First Team
So, I'm stuck on this compiler error, and google is giving me no help.
I'm still pretty new to C++, only about 4 weeks into my first programming class. This is a practice problem out of the back of the book, and I'm having a hell of a time figuring out what the hell the compiler wants me to do!

here is my code:

code:
#include <iostream>
using namespace std;

int main( )
{

double wages(16.78), overtime(25.17), sst(.05), fet(.14);
int union(10);
int numberDependents(0), hoursWorked(0);

cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);

        cout << "Please enter the total hours worked this week:";
        cin >> hoursWorked;
        cout << "Please enter the number of dependents you have:";
        cin >> numberDependents;

        double weeklyPay, socialSecurity, federalIncome, netPay, netpayD;
        int dep3(35);

        weeklyPay = wages * hoursWorked;
        socialSecurity = weeklyPay * sst;
        federalIncome = weeklyPay * fet;
        netPay = weeklyPay - socialSecurity - federalIncome;
        netpayD = weeklyPay - socialSecurity - federalIncome - dep3;

        cout << "Your net weekly pay is " << weeklyPay << endl;
        cout << "with $" << socialSecurity << " paid for Social Security,\n";
        cout << "$" << federalIncome << " paid for Federal Income Tax,\n"          
        cout << "$" << union << " paid for union dues,\n";

        if (numberDependents >= 3) {
        cout << "$" << dep3 << " paid for health insurance for your dependents,\n";
        cout << "Leaving you with a net total of $" << netpayD << " for the week.\n";
        }

        else
        cout << "Leaving you with a net total of $" << netPay << " for the week.\n";

        return(0);
}
and the compiler errors are:

bookProg6.cpp: In function ‘int main()’:
bookProg6.cpp:8: error: expected primary-expression before ‘int’
bookProg6.cpp:8: error: expected `;' before ‘int’
bookProg6.cpp:31: error: expected primary-expression before ‘union’
bookProg6.cpp:31: error: expected `;' before ‘union’

I don't understand what it's asking me for. I googled those compiler errors, and none of the results really have any relevance to my problem. Any help guys?

FigBug
Apr 27, 2002

Lemon Party - Lest we Forget

Sarah Sherman posted:

bookProg6.cpp: In function ‘int main()’:
bookProg6.cpp:8: error: expected primary-expression before ‘int’
bookProg6.cpp:8: error: expected `;' before ‘int’
bookProg6.cpp:31: error: expected primary-expression before ‘union’
bookProg6.cpp:31: error: expected `;' before ‘union’

union is a keyword, you can't use it for a variable name.
you are missing a semicolon on line 28

lmao zebong
Nov 25, 2006

NBA All-Injury First Team

FigBug posted:

union is a keyword, you can't use it for a variable name.
you are missing a semicolon on line 28

oh poo poo, thanks a lot! that fixed everything.
I originally had a semicolon there, but I guess I was tweaking the code trying to get union to work and I guess I accidentally deleted it.

Feral Integral
Jun 6, 2006

YOSPOS

Sarah Sherman posted:

oh poo poo, thanks a lot! that fixed everything.
I originally had a semicolon there, but I guess I was tweaking the code trying to get union to work and I guess I accidentally deleted it.

What IDE are you using? Most will tell you if a word is a reserved keyword by highlighting or bolding the word in question. This helps a lot when you're just getting started and are not familiar with all the keywords :)

very
Jan 25, 2005

I err on the side of handsome.
Why is my "this" pointer changing on every line of execution?

My program is crashing because this is changing to something weird like 0x00000001 or 0xffffffff or random junk as I step through the program. The functions worked fine with an earlier build but now I am converting everything over to use wxWidgets and now this is happening all over the place.

I am having a lot of trouble searching as "this" isn't exactly a unique word.

Edit: Actually maybe I have no idea what is going on. Is "this" as it shows up in the debugger supposed to change? Is it showing me the address of this, or something else? I went back to my old implementation and this never changes in any function.

Edit 2: Why are these pointers "expression cannot be evaluated"? They were just newed.

very fucked around with this message at 03:55 on Mar 13, 2008

FatCow
Apr 22, 2002
I MAP THE FUCK OUT OF PEOPLE
I'm using a stl set to hold multiple instances of a class. Is it considered poor form to make things 'mutable' that aren't used in the comparison operator to get around the implicit cast to const?

Steampunk Mario
Aug 12, 2004

DIAGNOSIS ACQUIRED

FatCow posted:

I'm using a stl set to hold multiple instances of a class. Is it considered poor form to make things 'mutable' that aren't used in the comparison operator to get around the implicit cast to const?

I'd probably have to see a specific example of where you'd need to modify data in a comparison operator, but only modifying builtins or calling non-const methods on the class or any nonmutable member classes would cause this issue. So, if you have a lot of data in a class and only some of it needs to be changed in a const function, then you only need to make that specific data mutable.

...But yeah, it's kind of bad form because mutable usually designates pretty specific functionality like access statistics and caching. The general rule is that the (visible) state of the object should never change in a const method.

That Turkey Story
Mar 30, 2003

very posted:

Why is my "this" pointer changing on every line of execution?

My program is crashing because this is changing to something weird like 0x00000001 or 0xffffffff or random junk as I step through the program. The functions worked fine with an earlier build but now I am converting everything over to use wxWidgets and now this is happening all over the place.

I am having a lot of trouble searching as "this" isn't exactly a unique word.

Your this pointer should never change. If you are in a member function and the this pointer is one value, then later on in the same function, this is a different value, then you are either writing past the end of a buffer that you allocated on the stack or you are writing to a memory location on the stack via a dangling pointer to something that used to be on the stack but has now left scope.

If there is no code that could be writing values as you step through your code, but this is still changing between lines, then you may have passed a pointer to a stack-allocated variable to another thread (i.e. via a call to some library you are using) and the value is being changed from that thread even though your local object had since left scope, meaning it is writing to whatever happens to be in that memory location now, which in this case is possibly your this pointer.

FatCow posted:

I'm using a stl set to hold multiple instances of a class. Is it considered poor form to make things 'mutable' that aren't used in the comparison operator to get around the implicit cast to const?

It's kind of hackish, have you considered using a map instead or are you unable to partition the type? If you have Boost you might also want to consider using a Multi-Index Container and modify the value with its "modify" function template.

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

very posted:

Edit: Actually maybe I have no idea what is going on. Is "this" as it shows up in the debugger supposed to change? Is it showing me the address of this, or something else? I went back to my old implementation and this never changes in any function.

Edit 2: Why are these pointers "expression cannot be evaluated"? They were just newed.


While in a method of an object, "this" is supposed to point to the instance that's currently executing the method. If it's pointing to invalid memory, something is very, very wrong. (If you're not in an object method, it'll just be undefined.)

It's expected to change as soon as you enter a new object. For example, in the following code if you step into each function call, it'll change as you enter the functions and be restored when you come back out. If you're not entering another function, it shouldn't change.

code:
SomeClass::someMethod()
{
  // "this" should point to the current instance of SomeClass
  object1->func();  // while in this method, "this" will point to object1
  object2->func();  // in this method, "this" will point to object2
  // "this" should be back to the SomeClass instance
}
Your other problem is a direct consequence of this one: in this contedxt m_world is a shortcut for this->m_world, and if "this" is invalid the whole thing is.

The most common reason for "this" to be invalid is if you call a method using a bad pointer, but this would only give you one single invalid value (and it usually crashes pretty quickly). If it keeps changing to a bunch of different bad values, something very weird is going on.

code:
delete obj1;
... some time later
obj1->func();
Depending on compiler and circumstances, this might crash right there, or get quite a ways into "func" with "this" set to whatever random memory obj1 is pointing to before bad things happen.

Mr VacBob
Aug 27, 2003
Was yea ra chs hymmnos mea
If you're debugging an optimized program, the debug info is probably wrong and giving you nonsense answers.

very
Jan 25, 2005

I err on the side of handsome.
Thanks both of you.

The thing that confuses me is that the entire program runs just fine even though this is pointing all over the place. I just tried adding one feature and one of the libraries I am using was sensible enough to crash when I passed it a this pointer value 0x00000001 and that is why I noticed the problem in the first place.

wxWidgets says to turn off optimization for "bizarre problems" and I guess this is a bizarre problem, so I did that and it works now.

Maybe I need up upgrade to VC++ 2008, but I'm afraid I will have to recompile every library I am using and I'll never get up and running again.

vvv I didn't realize they were on. I don't know why VC++ sets up the Debug configuration just like a release configuration by default when you do an empty project.

very fucked around with this message at 05:07 on Mar 13, 2008

more falafel please
Feb 26, 2005

forums poster

Mr VacBob posted:

If you're debugging an optimized program, the debug info is probably wrong and giving you nonsense answers.

This. Try it with optimizations off, or try printing the values you need instead of trusting the debugger, if you need those optimizations for debugging.

haveblue
Aug 15, 2005



Toilet Rascal
Optimizations and debugging are pretty much mutually exclusive; the compiler will tie your code in knots behind the scenes. Especially if it uses aggressive inlining.

FatCow
Apr 22, 2002
I MAP THE FUCK OUT OF PEOPLE

Drx Capio posted:

...But yeah, it's kind of bad form because mutable usually designates pretty specific functionality like access statistics and caching. The general rule is that the (visible) state of the object should never change in a const method.

That Turkey Story posted:

It's kind of hackish, have you considered using a map instead or are you unable to partition the type? If you have Boost you might also want to consider using a Multi-Index Container and modify the value with its "modify" function template.

Thanks. I switched to a map and pulled the items used in the index since they aren't needed other then for searching on.

FatCow fucked around with this message at 23:44 on Mar 13, 2008

Smackbilly
Jan 3, 2001
What kind of a name is Pizza Organ! anyway?

HB posted:

The first code copies the string constant into the variable-sized array a, the second creates a pointer to the string constant before attempting to change it. These compiled-in constants are read-only by default; if you're using GCC there's a flag you can use to allow writing to them.

This may just have been a slip on your part, but for new programmers it's important to note that the array a created by

code:
char a[] = "hello world";
is not variable-sized. Its size is implicit, but still static and determined at compile-time. The compiler will read the length of the string you are initializing it with (in this case 12), and convert it to

code:
char a[12] = "hello world";
before compiling.

haveblue
Aug 15, 2005



Toilet Rascal
Yeah, sorry, I meant that its size was determined at compile-time rather than typing-time.

floWenoL
Oct 23, 2002

HB posted:

Yeah, sorry, I meant that its size was determined at compile-time rather than typing-time.

What is this "typing-time"?

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

floWenoL posted:

What is this "typing-time"?

It's the pre-preprocessing state, of course! :downs:

Scaevolus
Apr 16, 2007

floWenoL posted:

What is this "typing-time"?

typing-time:
code:
char c[6] = "hello";
compile-time:
code:
char c[] = "hello";
typing-time is when you are editing the code

schnarf
Jun 1, 2002
I WIN.
I've got a class inheritance question. I'm writing a scheduler using templates, so that I'll have a generic framework for the scheduler, and the actual process function is virtual so that I can write a variety of schedulers for whatever datatype and scheduling algorithm I want. This is for an assigment. My question is, the schedulers that I implement, inheriting from my base class Scheduler<T> will not need to be templated; they'll use only one datatype because the algorithm will be specific to that datatype. How do I specify that the inherited class isn't templated, but rather uses a specific datatype?

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
code:
class IntScheduler : public Scheduler<int>
{
    // ...
};

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

schnarf posted:

I've got a class inheritance question. I'm writing a scheduler using templates, so that I'll have a generic framework for the scheduler, and the actual process function is virtual so that I can write a variety of schedulers for whatever datatype and scheduling algorithm I want. This is for an assigment. My question is, the schedulers that I implement, inheriting from my base class Scheduler<T> will not need to be templated; they'll use only one datatype because the algorithm will be specific to that datatype. How do I specify that the inherited class isn't templated, but rather uses a specific datatype?

Were you required to use both templates and inheritance in this assignment? Because it seems way more complicated than it's worth.

"Schedular<T>" is not a class. It's a family of classes, "Schedular<int>", "Schedular<string>", "Schedular<SomeOtherClass>", etc. So you have to pick just one individual class (ie. just one instantiation of the template) to inherit from:

code:
class IntegerSchedular : public Schedular<int>
{
  // method overrides
};

class StringSchedular : public Schedular<string>
{
  // method overrides
};
IntegerSchedular and StringSchedular aren't templated. But you can't take advantage of polymorphism this way, because IntegerSchedular and StringSchedular don't share any common base class! So you can't create a function that takes a "Schedular" and then pass it either IntegerSchedular or StringSchedular, because there's no such thing as just a Schedular.

One way to get around that is

code:
class SchedularBase
{
  // methods that don't depend on the type T, if any
};

class Schedular<T> : public SchedularBase
{
  // methods that do depend on the type T
};

class IntegerSchedular : public Schedular<int>
{
  // etc
};
Now you have SchedularBase as a base class of all schedulars - but one of the more important things a base class is used for is to enforce contracts (interfaces), and SchedularBase isn't very useful for that because some of the interface will depend on the type T and be declared in the templated class.

In summary, rethink this. You probably need generics OR inheritance, not both.

very
Jan 25, 2005

I err on the side of handsome.
I traced the actual problem I am having down to a function in a library that I am using (bullet) where the wrong function is being called. They aren't even the same prototype, or even in the same class hierarchy. The function that is supposed to be called is a simple getCount() type thing that returns an int, but the program actually goes to a different function entirely that returns a void, thus passing on garbage to the caller. The function that gets called takes some arguments by reference, so it is probably doing even more damage by clobbering whatever happens to be in those spots.

Does anybody know what would generally cause the wrong function to be called? I'm using VC++ express 2005.

A friend of mine thinks that the memory where function addresses are stored is getting clobbered somehow. Is that even possible? Would VC++ just let me do that? I put the code that breaks at the very beginning of my program and stepped through it with no other threads running, but it still goes to the wrong function.

I've also since rebuilt the library, but that didn't fix it either.

haveblue
Aug 15, 2005



Toilet Rascal

very posted:

A friend of mine thinks that the memory where function addresses are stored is getting clobbered somehow. Is that even possible? Would VC++ just let me do that? I put the code that breaks at the very beginning of my program and stepped through it with no other threads running, but it still goes to the wrong function.

I've also since rebuilt the library, but that didn't fix it either.

It wouldn't *knowingly* let you do that (not in C++, at least), but it can certainly get corrupted.

What relationship, if any, does the wrong function have with the correct one? Also, double-check the type of the pointer you're using to invoke the method.

very
Jan 25, 2005

I err on the side of handsome.

HB posted:

It wouldn't *knowingly* let you do that (not in C++, at least), but it can certainly get corrupted.

What relationship, if any, does the wrong function have with the correct one? Also, double-check the type of the pointer you're using to invoke the method.

Ok. I see something new here:

The caller's type is btPrimitiveManagerBase *, and the function being called is defined in there as virtual int get_primitive_count() const = 0; This obviously shouldn't work, right?

The thing that bothers me is that it does work just fine in an earlier version of my program. The difference being that I switched to using wxWidgets for my interface. I don't know how this is related, but it was such a major overhaul that I can't really pinpoint one thing that made it break.

In the version that works, the caller is still a btPrimitiveManagerBase *, but the function that gets called is in this class:

code:
class btGImpactCompoundShape	: public btGImpactShapeInterface
{
public:
	class CompoundPrimitiveManager:public btPrimitiveManagerBase
	{
		virtual int get_primitive_count() const
		{
			return (int )m_compoundShape->getNumChildShapes();
		}
	/* etc */
	}
/* etc */
}
But I don't see it getting casted to CompoundPrimitiveManager * anywhere. Maybe I should stick a cast in and recompile the library?

Adbot
ADBOT LOVES YOU

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

very posted:

But I don't see it getting casted to CompoundPrimitiveManager * anywhere. Maybe I should stick a cast in and recompile the library?

Unless you're dealing with multiple inheritance, you shouldn't need to worry about casting.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply