views:

480

answers:

4

I have a struct as follows, with a pointer to a function called "length" that will return the length of the chars member.

typedef struct pstring_t {
    char * chars;
    int (* length)();
} PString;

I have a function to return the length of the characters from a pointer to a PString:

int length(PString * self) {
    return strlen(self->chars);
}

I have a function initializeString() that returns a pointer to a PString:

PString * initializeString() {
    PString *str;
    str->length = &length;
    return str;
}

It is clear that I am doing something very wrong with my pointers here, because the str->length = &length line causes an EXC_BAD_ACCESS signal in my debugger, as does `return strlen(self->chars). Does anyone have any insights into this problem?

I specifically want to be able have the initializeString() function return a pointer to a PString, and the length function to use a pointer to a PString as input. This is just an experiment in implementing a rudimentary object-oriented system in C, but I don't have a lot of experience dealing with pointers head-on. Thanks for any help you can give me.

+2  A: 

The pointer str is never allocated. It should be malloc'd before use.

jgottula
Replace `PString *str;` with `PString *str = (PString *)malloc(sizeof(PString));`And ideally, call `free` with the pointer when done using it to avoid memory leaks.
jgottula
+2  A: 

My guess is that part of your problem is the parameter lists not matching.

int (* length)();

and

int length(PString * self)

are not the same. It should be int (* length)(PString *);.

...woah, it's Jon!

Edit: and, as mentioned below, your struct pointer is never set to point to anything. The way you're doing it would only work if you were declaring a plain struct, not a pointer.

str = (PString *)malloc(sizeof(PString));
jtbandes
Thanks a lot, Jacob. I'll go ahead and try that.
Jonathan Sterling
OK, `strlen(self->chars)` still gives me `EXC_BAD_ACCESS`.
Jonathan Sterling
+2  A: 

Maybe I am missing something here, but did you allocate any memory for that PString before you accessed it?

PString * initializeString() {
    PString *str;
    str = (PString *) malloc(sizeof(PString));
    str->length = &length;
    return str;
}
Sean
+1  A: 

Allocate memory to hold chars.

#include <stdio.h>
#include <stdlib.h>

typedef struct pstring_t {
        char * chars;
        int (* length)();
} PString;

int length(PString * self) {
    return strlen(self->chars);
}
PString * initializeString(int n)
{
    PString *str=(PString*)malloc(sizeof(PString));
    str->chars=(char *)malloc(sizeof(char)*n);
    str->length = length;
    return str;
}
int main()
{
  PString *p=initializeString(30);
  strcpy(p->chars,"Hello");
  printf("\n%d",p->length(p));
 return 0;
}
adatapost
Great answer!Question: I need to call free(p), but do I also need to free the chars?
Jonathan Sterling
I suppose I need to write a destructor.
Jonathan Sterling
There's no need to cast the return value of `malloc` in C. Also, you should initialise `str->chars` after you allocate it (ie. `str->chars[0] = '\0';`).
caf