Thread: Can't free

  1. #1
    Registered User
    Join Date
    Mar 2010
    Location
    Australia
    Posts
    174

    Can't free

    I'm working on an assignment that handles text and operations on the text. What I have so far is

    Code:
    //tests.c
    //Compile: gcc -Wall -Werror -O -o text textbuffer.c tests.c
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    #include <string.h>
    
    #include "textbuffer.h"
    
    void initialize (void);
    
    int main (int argc, char *argv[]) {
        initialize ();
        return EXIT_SUCCESS;
    }
    
    void initialize (void) {
        {
            TB TestSubject;
            printf("\nTest 1: Initialize with text \"abcd\"\n");   
            TestSubject = newTB("abcd");
            printf("Print text -\n%s\n", dumpTB(TestSubject));
            printf("Free text buffer\n");
            releaseTB(TestSubject);
            printf("Passed\n\n");
        }
        
        {
            TB TestSubject;
            printf("Test 2: Text = \"u\\nda\\nsexay \\nno homo\"\n");   
            TestSubject = newTB("u\nda\nsexay \nno homo");
            printf("Print text - \n%s\n", dumpTB(TestSubject));
            printf("Number of lines = %d\n", linesTB(TestSubject));
            printf("Free text buffer\n");
            releaseTB(TestSubject);
            printf("Attempt to find numLines should result in error:\n");
            printf("%d\n", linesTB(TestSubject));
            printf("Passed\n\n");
        }
        
        return;
    }

    Code:
    //textbuffer.c
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    
    #include "textbuffer.h"
    
    typedef struct textbuffer *TB;
    struct textbuffer {
        char *text;
    	int numLines;
    };
    
    /* Allocate a new textbuffer whose contents is initialised with the text given
     * in the array.
     */
    TB newTB (char text[]) {
    	TB Buff = malloc(sizeof(struct textbuffer));
    	assert (Buff != NULL);
    	
    	int lineCount = 1;
    	int length = strlen(text);
    	int i;
    	
    	for (i=0; i<length; i++) {
    	    if (text[i] == '\n')
    	        lineCount++;
    	}
    	Buff->numLines = lineCount;
    	
    	Buff->text = malloc(sizeof(char)*strlen(text));
    	strcpy(Buff->text, text);
    	
    	return Buff;
    }
    
    
    /* Free the memory occupied by the given textbuffer.  It is an error to access
     * the buffer afterwards.
     */
    void releaseTB (TB tb) {
        free(tb->text);
        free(tb);
    }
    
    /* Allocate and return an array containing the text in the given textbuffer.
     */
    char *dumpTB (TB tb) {
        return tb->text;
    }
    
    
    /* Return the number of lines of the given textbuffer.
     */
    int linesTB (TB tb) {
        return tb->numLines;
    }
    With a header file for the function declarations.

    My problem is that I can't seem to free the text and struct itself because when I call releaseTB which is supposed to free, I can still access the struct with no problem.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I suppose that depends on what you mean by "error" -- line 38 (in your main program) is an error, but a logic error, not a runtime error. The memory referenced by that pointer still exists, and if you're quick about it the memory might not have gotten reused yet, but there will always be some sort of data there, just maybe not your data.

    (EDIT: Hence good practice if you don't trust yourself or your other programmers is to set the pointer to NULL after you free it, which will cause a runtime error when you try to dereference it.)

  3. #3
    Registered User
    Join Date
    Mar 2010
    Location
    Australia
    Posts
    174
    Quote Originally Posted by tabstop View Post
    I suppose that depends on what you mean by "error" -- line 38 (in your main program) is an error, but a logic error, not a runtime error. The memory referenced by that pointer still exists, and if you're quick about it the memory might not have gotten reused yet, but there will always be some sort of data there, just maybe not your data.

    (EDIT: Hence good practice if you don't trust yourself or your other programmers is to set the pointer to NULL after you free it, which will cause a runtime error when you try to dereference it.)
    That makes perfect sense! Thank you tabstop.

    edit: Just one more thing. If I set the pointer to the struct to NULL, then I've basically lost the position of the struct in memory, hence I've also lost the position of the pointer char *text, so I'm wondering if the text pointer even needs to be set to NULL?

    Is the pointer freed (does it matter if it isn't?) or is it only the malloced array of text that's freed?
    Last edited by Mentallic; 12-09-2013 at 08:45 PM.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Mentallic
    If I set the pointer to the struct to NULL, then I've basically lost the position of the struct in memory, hence I've also lost the position of the pointer char *text, so I'm wondering if the text pointer even needs to be set to NULL?
    Generally, if a pointer might be used after that point, setting it to be a null pointer is good practice. Otherwise, were it to be used again before being assigned to, the resulting bug could be harder to track down. Furthermore, it enables a check for a null pointer later on that would actually work as expected.

    Quote Originally Posted by Mentallic
    Is the pointer freed (does it matter if it isn't?) or is it only the malloced array of text that's freed?
    When you call free with a pointer, it is what the pointer points to that is freed.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Mar 2010
    Location
    Australia
    Posts
    174
    Ok cheers for that

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 12-28-2012, 04:07 PM
  2. new license-free lock-free data structure library published
    By Toby Douglass in forum Projects and Job Recruitment
    Replies: 19
    Last Post: 12-22-2009, 02:33 AM
  3. Malloc - Free giving double free or corruption error
    By andrew.bolster in forum C Programming
    Replies: 2
    Last Post: 11-02-2007, 06:22 AM
  4. What's cooler than free boobs? 5 free assembly books from AMD.
    By Silvercord in forum A Brief History of Cprogramming.com
    Replies: 47
    Last Post: 02-13-2003, 08:22 PM