Pointers problem.

Hi,

I recently got an Ethernet module and wanted to make a basic web server. After browsing a couple of the Ethernet and SD examples I got it working with GET requests. However, since adding support for multiple files (like getting the index page, then the css page etc...) I've come across (what I think is) a pointer problem.

I must admit I am not too clued up on pointers, so any help would be appreciated. I did try researching my problem, but as I'm not entirely sure what the problem is, I didn't get very far.

This is the problematic function:

char *filepath;
char *filename;
char *extension;

...

void handleGet(char *filepath) {  
    if(!strcmp(filepath, "/")) {
        filepath = "index.htm";
    }
    Serial.println(filepath);
    
    if(SD.exists(filepath)) {
        contentFile = SD.open(filepath);
        filename = strtok(filepath, ".");
        extension = strtok(NULL, ".");
        
        if(!strcmp(extension, "css")) {
            type = "text/css";
        } else if(!strcmp(extension, "htm")) {
            type = "text/html";
        } else if(!strcmp(extension, "txt")) {
            type = "text/plain";
        }
        if(contentFile) {
            client.println("HTTP/1.1 200 OK");
            client.print("Content-Type: ");
            client.println(type);
            client.println("Connection: close");
            client.println();
            while(contentFile.available()) {
                client.print((char)contentFile.read());   
            }
        } else {
            handle404();
        }
        contentFile.close();
    } else {
        handle404();
    }
}

The problem comes when loading the index.htm file for the second time.
Initially it works, the index.htm file and the style.css file are served and everything works fine.
However, when I go to refresh the page, the 'filepath' variable is set to "index" instead of "index.htm" (this is done on the second line). I thought this was probably a problem with reusing a pointer, but I'm not sure.

If any further information is needed I am more than willing to provide.

Any ideas what the problem might be?

Thanks.

Given that filename is a char pointer, what do you think happens here:

     filepath = "index.htm";

Through debugging I found that 'filepath' gets set to "index" rather than "index.htm", but as to why I don't know. I'm slightly confused as to why it works the first time but not the second. Could you give a brief explanation?

Thanks a lot :slight_smile:

Your basic problem is that you are not allocating any space for storing your strings.

In general, any time you see var = "constant" in C, there is probably a bug somewhere unless it is a declaration and initialization.

You need to do this:

// Allocate *space* for char arrays
char filepath[32];
char filename[16];
char extension[16];

//...

strcpy(filepath, "index.htm");

string constants like "index.htm" are not writeable, they should be considered read only memory. strtok() wrote a '\0' into your constant string.

This:

        filepath = "index.htm";

Makes file path point to an area of memory that has been populated with "index.htm". It doesn't copy the string or assign it. strtok puts nulls in the string it's searching for tokens in. So when you use strtok to look for '.', it overwrites the '.' in index and returns a pointer to the string.

Next time you do this:

        filepath = "index.htm";

the memory pointed to by file path contains the changed data so although the htm is still there, it isn't printed because there is a character 0 instead of the '.' which indicates end of string.

wildbill:
He shouldn't be writing to wherever "Index.htm" is stored, anyway. It is considered read only memory. This might be one of those differences between C and C++, but I don't think it is wise to treat "Index.htm" as writable store.

Thank you all for your replies, the explanations made sense and my problem has now been solved.

Still trying to get the hand of pointers and memory in general. strcpy to the rescue!

+karma to all