Home > Archive > Objective C > November 2005 > allocating memory
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
|
|
| Santa Claus 2005-11-15, 7:59 am |
| say i have a structure and referenced it as an array
struct gsskills
{
NSMutableString *skillname;
long skillvalue;
long bonusvalue;
} mygsskills[48];
how would i do this as a pointer to an array and then how would i allocate memory for it?
i'm assuming i'd reference it as *mygsskills[something]
| |
| Daniel Johnson 2005-11-15, 7:59 am |
| My C is is a little rusty, but I believe I can still remember the
answer to this one.
On 2005-11-15 05:44:30 -0500, Santa Claus <santa@northpole.com> said:
> say i have a structure and referenced it as an array
>
> struct gsskills
> {
> NSMutableString *skillname;
> long skillvalue;
> long bonusvalue;
> } mygsskills[48];
You will find using a structure like this awkward, since you will need
to in some way deallocate 'skillname', unless all skill names are
constants (in which case they are not mutable). You may be better off
with a gsskills *class*, and an NSArray or NSMutableArray of them. Then
you get Apple's much easier to use memory management features, and all
is right with the world.
But let's say your really want to do this.
> how would i do this as a pointer to an array and then how would i
> allocate memory for it?
You already have. The declaration above allocates space for 48
gsskills, as a local or global variable depending on where it appears.
You can access them as mygsskills[x], and obtain a pointer to one as
&mygskills[x].
If you do not want to allocate 48 skills in this way, omit the
"mygskills[48]" part.
If you want to allocate these guys on the heap, C style, you can do it
this way:
struct mygsskills *skillsPointers=calloc(count,sizeof(stru
ct gskills));
calloc() is part of the C standard library, and is found in <stdlib.h>.
This gives you a zero-initialized array of gskills, and a pointer to it
in 'skillsPointer'. You would then initialize the content of each of
the structures.
Use free() to deallocate this array, thus:
free(skilsPointers);
But do not forget to somehow deal with all those skillnames before you
do that. That might take this form:
for(i=0;i<count;++i)
{
[skillsPointer[i].skillname release];
}
Notice that you need to store the 'count' of the array separately. C
does not track this for you, and you need it to deallocate the data in
the structures in this case.
Finally, the keyword 'struct' is needed here because C is kinda
old-skoool that way. You can declare the structure this way to avoid it:
typedef struct
{
/* members */
} mygskills;
This declares a structure type that has no name, and a type definition
to refer to you. You use the typedef in variable declaratiions,
sizeof(), etc:
ygsskills *skillsPointers=calloc(count,sizeof(gski
lls));
> i'm assuming i'd reference it as *mygsskills[something]
No, no asterix. You do this:
mygskills[32].bonusvalue
or
skillsPointer[32].bonusvalue
This is a Very Weird thing about C: array names 'decay' into pointers
(to the first element), and the indexing operator (x[n]) works with
pointers. It is actually exactly equivalent to *(x+n), but in this
case the meaning intended makes x[n] preferable.
Anyway this means that "skillsPointer[32].bonusvalue" works out to this:
(*(skillsPointer+32)).bonusvalue;
C pointer arithmetic works like array indixing. +1 means "move foward
one *element*" not one *byte*. Thus, this calculates the address of the
33rd element, then obtains the bonusvalue within.
It is the 33rd element because the first element is +0, i.e., it is
what skillsPointer already points at.
.... hope I got all that right. It's coal in my stocking come Christmas
if I didn't, I guess. :D
| |
| David Phillip Oster 2005-11-15, 7:05 pm |
| In article <santa-E8121D.05443015112005@news.giganews.com>,
Santa Claus <santa@northpole.com> wrote:
> say i have a structure and referenced it as an array
>
> struct gsskills
> {
> NSMutableString *skillname;
> long skillvalue;
> long bonusvalue;
> } mygsskills[48];
>
>
> how would i do this as a pointer to an array and then how would i allocate
> memory for it?
>
> i'm assuming i'd reference it as *mygsskills[something]
You wouldn't. You'd say:
typedef struct gsskills
{
NSMutableString *skillname;
long skillvalue;
long bonusvalue;
} gsskills ;
gsskills* mygsskills;
#define kCOUNT 48
if(nil != (mygsskills = (gsskills*) calloc(kCOUNT, sizeof(gsskills)))){
int i;
for(i = 0; i < kCOUNT; ++i){
mygsskills[i].skillname = [[NSMutableString alloc] init];
}
.....
for(i = 0; i < kCOUNT; ++i){
[mygsskills[i].skillname release];
}
free(mygsskills)
}
| |
| Santa Claus 2005-11-15, 7:05 pm |
| In article <oster-206463.09520615112005@newsclstr02.news.prodigy.com>,
David Phillip Oster <oster@ieee.org> wrote:
> In article <santa-E8121D.05443015112005@news.giganews.com>,
> Santa Claus <santa@northpole.com> wrote:
>
>
> You wouldn't. You'd say:
>
> typedef struct gsskills
> {
> NSMutableString *skillname;
> long skillvalue;
> long bonusvalue;
> } gsskills ;
>
> gsskills* mygsskills;
>
> #define kCOUNT 48
>
> if(nil != (mygsskills = (gsskills*) calloc(kCOUNT, sizeof(gsskills)))){
> int i;
> for(i = 0; i < kCOUNT; ++i){
> mygsskills[i].skillname = [[NSMutableString alloc] init];
> }
>
> ....
>
> for(i = 0; i < kCOUNT; ++i){
> [mygsskills[i].skillname release];
> }
> free(mygsskills)
> }
ok, my REAL problem is i have too many global variables and need to find some way of lowering the number of global variables
or increasing the memory allowed for global variables. I thought if i did a structure to the variables and then allocated
memory for that block, i'd be able to free up global memory space.
the problem occurred when i added several variables and features to my plugin and suddenly it started to crash all over the
time and always in the same exact location, someplace that worked before. in my initialization routine i allocate a global nsstring.
when i get to set it, it crashes the main program as if it wasn't being allocated. but if i re-initialize the variable, it works flawlessly but i create a memory leak.
global area:
NSMutableString *directionsLine;
initialization routine:
directionsLine = [[NSMutableString alloc] init];
usage:
[directionsLine setString: [NSMutableString stringWithString: mystring1]];
alternate test usage to see if that's the line failing:
[directionsline setString: @"nothing here"];
a NSLog before the setString gets executed but a NSLog after the setString doesn't and the program crashes.
something's deallocating the memory for directionLine somehow.
| |
| David Phillip Oster 2005-11-15, 9:58 pm |
| In article <santa-21E9B2.18303115112005@news.giganews.com>,
Santa Claus <santa@northpole.com> wrote:
> ok, my REAL problem is i have too many global variables and need to find some
> way of lowering the number of global variables
> or increasing the memory allowed for global variables. I thought if i did a
> structure to the variables and then allocated
> memory for that block, i'd be able to free up global memory space.
>
> the problem occurred when i added several variables and features to my plugin
> and suddenly it started to crash all over the
> time and always in the same exact location, someplace that worked before. in
> my initialization routine i allocate a global nsstring.
> when i get to set it, it crashes the main program as if it wasn't being
> allocated. but if i re-initialize the variable, it works flawlessly but i
> create a memory leak.
>
> global area:
> NSMutableString *directionsLine;
>
> initialization routine:
> directionsLine = [[NSMutableString alloc] init];
>
> usage:
> [directionsLine setString: [NSMutableString stringWithString: mystring1]];
>
> alternate test usage to see if that's the line failing:
> [directionsline setString: @"nothing here"];
>
> a NSLog before the setString gets executed but a NSLog after the setString
> doesn't and the program crashes.
>
> something's deallocating the memory for directionLine somehow.
gdb is your friend.
You can have NSLog() print the hex value of directionsLine when it is
allocated.
You can set a conditional breakpoint on -[NSObject dealloc] that only
fires when self is equal to that address.
You can, in two separate NSLog()s, print the hex value of directionsLine
right before the crash, and you can even use:
po directionsLine
in the gdb debugger console window to have it show to you.
If you discover that & directionsLine is getting trashed, you can use
binary search to find the offender.
|
|
|
|
|