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

/* a structure that defines a string buffer */
typedef struct strbuf {
    char   *contents;   /* pointer to dynamically allocated buffer contents */
    size_t  length;     /* number of characters in buffer (excluding '\0') */
} StringBuffer;

/* function prototypes */
StringBuffer *strbuf_new(const char *cstr);
StringBuffer *strbuf_append(StringBuffer *buf, const char *cstr);
StringBuffer *strbuf_insert(StringBuffer *buf, const char *cstr, size_t pos);
StringBuffer *strbuf_reset(StringBuffer *buf, const char *cstr);
void          strbuf_free(StringBuffer *buf);

int main(void)
{
    StringBuffer *sb = NULL;

    sb = strbuf_new("Hello");
    if (sb == NULL)
        printf("*** Failed to create buffer");
    else {
        printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);
        if (strbuf_append(sb, " world") == NULL)
            printf("*** Failed to append\n");
        printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);

        if (strbuf_reset(sb, NULL) == NULL)
            printf("*** Failed to reset\n");
        printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);
        if (strbuf_append(strbuf_append(strbuf_append(sb, "I"), " am"), " Sam") == NULL)
            printf("*** Failed to append\n");
        printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);

        strbuf_free(sb);
    }

    sb = strbuf_new(NULL);
    if (sb == NULL)
        printf("*** Failed to create buffer");
    else {
        printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);
        if (strbuf_append(sb, "aaaaa") == NULL)
            printf("*** Failed to append\n");
        printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);
        if (strbuf_insert(sb, "bbb", 2) == NULL)
            printf("*** Failed to insert\n");
        printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);

        if (strbuf_reset(sb, "aaaaa") == NULL)
            printf("*** Failed to reset\n");
        if (strbuf_insert(sb, "bbb", 0) == NULL)
            printf("*** Failed to insert\n");
        printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);

        if (strbuf_reset(sb, "aaaaa") == NULL)
            printf("*** Failed to reset\n");
        if (strbuf_insert(sb, "bbb", 10) == NULL)
            printf("*** Failed to insert\n");
        printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);
        
        if (strbuf_insert(strbuf_insert(strbuf_reset(sb, "aaa"), "bbb", 1), "ccc", 5) == NULL)
            printf("*** Failed to reset/insert\n");
        printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);

        strbuf_free(sb);
    }
    
    // the following calls are meant to fail
    
    if (strbuf_reset(NULL, "stuff") == NULL)
        printf("*** Failed to reset\n");
        
    if (strbuf_append(NULL, "stuff") == NULL)
        printf("*** Failed to append\n");

    if (strbuf_insert(NULL, "stuff", 0) == NULL)
        printf("*** Failed to insert\n");
    
    return 0;
}

/*
int main(void)
{
    StringBuffer *sb = NULL;         // buffer does not exist yet

    sb = strbuf_new("Hello");        // new buffer allocated containing "Hello"
    printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);

    strbuf_append(sb, " world");     // buffer contains "Hello world"
    printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);

    strbuf_reset(sb, NULL);          // buffer contains empty string ""
    printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);
    
    strbuf_append(strbuf_append(strbuf_append(sb, "I"), " am"), " Sam");  // buffer contains "I am Sam"
    printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);

    strbuf_free(sb);                 // buffer deallocated (contents no longer accessible)
    
    sb = strbuf_new(NULL);           // new buffer allocated containing empty string ""
    printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);
    
    strbuf_append(sb, "aaaaa");      // buffer contains "aaaaa"
    printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);
    
    strbuf_insert(sb, "bbb", 2);     // buffer contains "aabbbaaa"
    printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);

    strbuf_reset(sb, "aaaaa");       // buffer contains "aaaaa"
    printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);
    
    strbuf_insert(sb, "bbb", 0);     // buffer contains "bbbaaaaa"
    printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);

    strbuf_reset(sb, "aaaaa");       // buffer contains "aaaaa"
    printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);
    
    strbuf_insert(sb, "bbb", 10);    // buffer contains "aaaaabbb"
    printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);
    
    strbuf_insert(strbuf_insert(strbuf_reset(sb, "aaa"), "bbb", 1), "ccc", 5);  // buffer contains "abbbaccca"
    printf("length = %2u: \"%s\"\n", (unsigned)sb->length, sb->contents);

    strbuf_free(sb);                    // buffer deallocated (contents no longer accessible)
    
    return 0;
}
*/


/*****************************************************************************/
/******************                                ***************************/
/****************    IMPLEMENT THE FUNCTIONS HERE    *************************/
/*****************                                 ***************************/
/*****************************************************************************/

StringBuffer *strbuf_new(const char *cstr){
	StringBuffer *strbuf = (StringBuffer*) malloc(sizeof(StringBuffer));
	
	if(strbuf == NULL){
		return NULL;
	}
	else{
		if(cstr != NULL){
			char *str = (char*) malloc(sizeof(char) * (strlen(cstr) + 1));
			
			if(str == NULL){
				return NULL;
			}
			else{
				strcpy(str,cstr);
				
				strbuf->contents = str;
				strbuf->length = strlen(str);
			}
		}
		else{
			char *blankstr = (char*) malloc(sizeof(char));
				
			if(blankstr == NULL){
				return NULL;
			}
			else{
				strbuf->contents = blankstr;
				strcpy(strbuf->contents,"");
				strbuf->length = strlen(strbuf->contents);
			}
		}
	}
	
	return strbuf;	
}

StringBuffer *strbuf_append(StringBuffer *buf, const char *cstr){
	if(buf == NULL){
		return NULL;
	}
	
	if(cstr == NULL){
		return buf;
	}
	else{
		char *newstr = (char*) realloc(buf->contents, buf->length + strlen(cstr));

		if (newstr == NULL){
			return NULL;
		}
		else {
			buf->contents = newstr;
			strcat(buf->contents, cstr);
			buf->length = strlen(buf->contents);
		}
	}
	
	return buf;	
}

StringBuffer *strbuf_insert(StringBuffer *buf, const char *cstr, size_t pos){
	if(buf == NULL){
		return NULL;
	}
	
	if(cstr == NULL){
		return buf;
	}
	else{
		char *newstr = (char*) realloc(buf->contents, buf->length + strlen(cstr));

		if (newstr == NULL)
			return NULL;
		else {
			if(pos >= buf->length){
				buf->contents = newstr;
				strcat(buf->contents, cstr);
				buf->length = strlen(buf->contents);
			}
			else{
				buf->contents = newstr;
				strcat(buf->contents, cstr);
				buf->length = strlen(buf->contents);
			}
		}
	}
	
	return buf;	
}

StringBuffer *strbuf_reset(StringBuffer *buf, const char *cstr){
	if(buf == NULL){
		return NULL;
	}
	
	if(cstr == NULL){
		char *newstr = (char*) malloc(sizeof(char));
			
		if(newstr == NULL){
			return NULL;
		}
		else{
			buf->contents = newstr;
			strcpy(buf->contents,"");
			buf->length = strlen(buf->contents);
		}
	}
	else{
		char *newstr = (char*) realloc(buf->contents, strlen(cstr));

		if (newstr == NULL){
			return NULL;
		}
		else {
			buf->contents = newstr;
			strcpy(buf->contents, cstr);
			buf->length = strlen(buf->contents);
		}
	}
	
	return buf;
}

void strbuf_free(StringBuffer *buf){
	if(buf != NULL){
		free(&buf->length);
		free(&buf->contents);
		free(buf);
	}		
}

OK, so the problem is that the program crashes on line 41, which to me makes no sense because I have already successfully called that function (line 22). If I comment that line out it does not crash ! I have tested everything I can think of, and yes it is a homework assignment and it is due tomorrow (Friday July 2nd, by 11:59pm). PLEASE HELP ME ! I am very lost.

Hi,
I hav seen ur program. Since u r in a hurry I hv not wasted time in understanding what ur program does, rather I tried to check out the exception that u r getting.

See, ur problem is not with the

Line 41: sb = strbuf_new(NULL);

that u r thinking.
It's with the

strbuf_free(sb);

wherever u hv used.
In that function u hv tried to free both the members of the "buf" structure variable, which is wrong.
The static member "length" will be freed by using free(buf); itself. U cannot free it the way u did and it is not required.
One more error u did is by using free(&buf->contents); for the other member "contents", which being a pointer has to freed. But the syntax will be free(buf->contents); i.e no & operator.

So, ur changed code for the function strbuf_free will be

void strbuf_free(StringBuffer *buf){
if(buf != NULL){
//  free(&buf->length);
  free(buf->contents);
  free(buf);
 }	
}

Make the changes, compile it, I think it will be OK.

Cheers,

Hi, thanks for the quick reply, but I changed the strbuf_free function but the program still crashes at the same point.

Also for the strbuf_insert function, I cannot figure out how to insert the contents of cstr into buf->contents at the specified position, pos.

eg) buf->contents = "aaaaa"
cstr = "bbb"
pos = 2

the result should be "aabbbaaa", thanks again for the help I really appreciate it.

I hv compiled the program with the changed "strbuf_free" function in my Fedora PC with GCC compiler. Its working fine with the output :

length =  5: "Hello"
length = 11: "Hello world"
length =  0: ""
length =  8: "I am Sam"
length =  0: ""
length =  5: "aaaaa"
length =  8: "aaaaabbb"
length =  8: "aaaaabbb"
length =  8: "aaaaabbb"
length =  9: "aaabbbccc"
*** Failed to reset
*** Failed to append
*** Failed to insert

Though I am not gone through the code (so no idea abt the output), but its not crashing...
First u confirm that u correctly made the changes, if still it is crashing then tell me which compiler u r using. Later I will see inside ur functions for generating what output u want..

Check it out...

length =  5: "Hello"
length = 11: "Hello world"
length =  0: ""
length =  8: "I am Sam"
Problem signature:
  Problem Event Name:	APPCRASH
  Application Name:	a.exe
  Application Version:	0.0.0.0
  Application Timestamp:	4c2d796f
  Fault Module Name:	ntdll.dll
  Fault Module Version:	6.1.7600.16385
  Fault Module Timestamp:	4a5bdb3b
  Exception Code:	c0000005
  Exception Offset:	00033913
  OS Version:	6.1.7600.2.0.0.256.1
  Locale ID:	1033
  Additional Information 1:	0820
  Additional Information 2:	0820d7c80ba97540401de55e33fece4c
  Additional Information 3:	75ec
  Additional Information 4:	75ec15f986f03e2ae509217076914232

Read our privacy statement online:
  http://go.microsoft.com/fwlink/?linkid=104288&clcid=0x0409

If the online privacy statement is not available, please read our privacy statement offline:
  C:\Windows\system32\en-US\erofflps.txt

i am using gcc for my compiler. i get that output and then, a.exe has crashed and that is the error report

Edited 6 Years Ago by xxpokerxx: n/a

Just some extra information about the strbuf_insert function, lines 223 - 225 should be replaced by the code to do what i asked about previously.

buf->contents = newstr;
strcat(buf->contents, cstr);
buf->length = strlen(buf->contents);

The following is what the program should produce if the function is implemented correctly, i have everything else working fine but this one has me stumped.

length =  5: "Hello"
length = 11: "Hello world"
length =  0: ""
length =  8: "I am Sam"
length =  0: ""
length =  5: "aaaaa"
length =  8: "aabbbaaa"
length =  8: "bbbaaaaa"
length =  8: "aaaaabbb"
length =  9: "abbbaccca"
*** Failed to reset
*** Failed to append
*** Failed to insert

Edited 6 Years Ago by xxpokerxx: n/a

I am not getting any useful information from ur error report. I wanted the error message that GCC is giving. For example, when I ran ur earlier program I got the exception from GCC like :

-bash-3.2$ ./sam
length =  5: "Hello"
length = 11: "Hello world"
length =  0: ""
length =  8: "I am Sam"
*** glibc detected *** ./sam: free(): invalid pointer: 0x08d6200c ***
======= Backtrace: =========
/lib/libc.so.6[0x60a3a4]
/lib/libc.so.6(cfree+0x96)[0x60c356]
./sam[0x8048ca1]
./sam[0x8048692]
/lib/libc.so.6(__libc_start_main+0xe5)[0x5b16e5]
./sam[0x80484b1]
======= Memory map: ========
00576000-00596000 r-xp 00000000 fd:00 901283     /lib/ld-2.9.so
00597000-00598000 r--p 00020000 fd:00 901283     /lib/ld-2.9.so
00598000-00599000 rw-p 00021000 fd:00 901283     /lib/ld-2.9.so
0059b000-00709000 r-xp 00000000 fd:00 901290     /lib/libc-2.9.so
00709000-0070b000 r--p 0016e000 fd:00 901290     /lib/libc-2.9.so
0070b000-0070c000 rw-p 00170000 fd:00 901290     /lib/libc-2.9.so
0070c000-0070f000 rw-p 0070c000 00:00 0
00879000-00886000 r-xp 00000000 fd:00 901318     /lib/libgcc_s-4.3.2-20081105.so.1
00886000-00887000 rw-p 0000c000 fd:00 901318     /lib/libgcc_s-4.3.2-20081105.so.1
009eb000-009ec000 r-xp 009eb000 00:00 0          [vdso]
08048000-08049000 r-xp 00000000 fd:02 1393787    /root/sam
08049000-0804a000 rw-p 00000000 fd:02 1393787    /root/sam
08d62000-08d83000 rw-p 08d62000 00:00 0          [heap]
b7600000-b7621000 rw-p b7600000 00:00 0
b7621000-b7700000 ---p b7621000 00:00 0
b77f6000-b77f8000 rw-p b77f6000 00:00 0
b780e000-b780f000 rw-p b780e000 00:00 0
bf965000-bf97a000 rw-p bffeb000 00:00 0          [stack]
Aborted

That is after the line print "I am Sam" the exception message is displayed by GCC (in LINUX konsole).

In ur case the error report doesn't give any clue for the problem. Where are u running the application, using any IDE ??
However, U can try debugging it using GDB and inform me for any further clue.
Anywaz, I will check the "strbuf_insert" function and let u know.

Sorry for late...I had some official work to do...
I have made some updations for ur "strbuf_insert" function. It is giving output as expected.
Check it and tell me whether it is working for u.

StringBuffer *strbuf_insert(StringBuffer *buf, const char *cstr, size_t pos){

        if(buf == NULL){
                return NULL;
        }

        if(cstr == NULL){
                return buf;
        }
        else{
                char *newstr = (char*) realloc(buf->contents, buf->length + strlen(cstr));
                char *temp = (char*) malloc(buf->length - pos); //Temporary variable to store intermediate string value

                if (newstr == NULL)
                        return NULL;
                else {
                        if(pos >= buf->length){
                                buf->contents = newstr;
                                strcat(buf->contents, cstr);
                                buf->length = strlen(buf->contents);
                        }
                        else{
                                buf->contents = newstr;
                                temp = strndup(buf->contents + pos, buf->length - pos); //Storing the last part of the string
                                buf->contents[pos] = '\0';
                                strcat(buf->contents, cstr);    //Adding the second string
                                strcat(buf->contents, temp);    //Adding back the last part of the original string
                                buf->length = strlen(buf->contents);
                        }
                }
        }

        return buf;
}

Note: Still I am not getting any exception.

You are a life saver ! I still have no idea why mine is crashing (gcc gives no error but the a.exe crashes) on my windows x64, however i took my file to my Linux x64 system and voila it works like a charm. After seeing your strbuf_insert it makes so much sense to me, thanks a lot.

This question has already been answered. Start a new discussion instead.