Hello DaniWeb!

I've found your website very useful for previous problems in my course, but this time I've come across something I just can't figure out.

I'm attempting to create a program thats instructions are defined in the code.

I've used a previous post as a guideline, and it was stated that it was fixed but mine just wont work.

After compiling the code using GCC I receive

length = 5: "Hello"
length = 11: "Hello World"
length = 0: ""
length = 8: "I am Sam"

then assgn2.exe has stopped working

Problem signature:
Problem Event Name: APPCRASH
Application Name: assgn2.exe
Application Version: 0.0.0.0
Application Timestamp: 4dfb5c1e
Fault Module Name: ntdll.dll
Fault Module Version: 6.1.7600.16695
Fault Module Timestamp: 4cc7ab86
Exception Code: c0000005
Exception Offset: 00032ba8
OS Version: 6.1.7600.2.0.0.256.1
Locale ID: 1033
Additional Information 1: 0a9e
Additional Information 2: 0a9e372d3b4ad19135b953a78882e789
Additional Information 3: 0a9e
Additional Information 4: 0a9e372d3b4ad19135b953a78882e789

heres the code:

Any help would be appreciated

#include <stdlib.h>
#include <stdio.h>
#define _GNU_SOURCE
#include <string.h>
#include "ansidecl.h"
#include <stddef.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    *************************/
/*****************                                 ***************************/
/*****************************************************************************/ 

extern size_t	strlen (const char*);
extern PTR	malloc (size_t);
extern PTR	memcpy (PTR, const PTR, size_t);

char *
strndup (const char *s, size_t n)
{
  char *result;
  size_t len = strlen (s);

  if (n < len)
    len = n;

  result = (char *) malloc (len + 1);
  if (!result)
    return 0;

  result[len] = '\0';
  return (char *) memcpy (result, s, len);
}
StringBuffer *strbuf_new(const char *cstr){
	StringBuffer *strbuf = (StringBuffer*) malloc(sizeof(StringBuffer));
	if(strbuf == NULL){
		return NULL;
	}
	else{
		if(cstr != NULL){
			char *string = (char*) malloc(sizeof(char) * (strlen(cstr) + 1));
			if(string == NULL){
				return NULL;
			}
			else{
				strcpy(string,cstr);
				strbuf->contents = string;
				strbuf->length = strlen(string);
			}
		}
		else{
			char *NULLString = (char*) malloc(sizeof(char));
			if(NULLString == NULL){
				return NULL;
			}
			else{
				strbuf->contents = NULLString;
				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 *newString = (char*) realloc(buf->contents, buf->length + strlen(cstr)); 
		if (newString == NULL){
			return NULL;
		}
		else {
			buf->contents = newString;
			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 *newString = (char*) realloc(buf->contents, buf->length + strlen(cstr));
                char *tempString = (char*) malloc(buf->length - pos); //Temporary variable to store intermediate string value
                if (newString == NULL)
                        return NULL;
                else {
                        if(pos >= buf->length){
                                buf->contents = newString;
                                strcat(buf->contents, cstr);
                                buf->length = strlen(buf->contents);
                        }
                        else{
                                buf->contents = newString;
                                tempString = 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, tempString);    //Adding back the last part of the original string
                                buf->length = strlen(buf->contents);
                        }
                }
        } 
        return buf;
}
StringBuffer *strbuf_reset(StringBuffer *buf, const char *cstr){
	if(buf == NULL){
		return NULL;
	} 
	if(cstr == NULL){
		char *newString = (char*) malloc(sizeof(char));
 
		if(newString == NULL){
			return NULL;
		}
		else{
			buf->contents = newString;
			strcpy(buf->contents,"");
			buf->length = strlen(buf->contents);
		}
	}
	else{
		char *newString = (char*) realloc(buf->contents, strlen(cstr));
 
		if (newString == NULL){
			return NULL;
		}
		else {
			buf->contents = newString;
			strcpy(buf->contents, cstr);
			buf->length = strlen(buf->contents);
		}
	}
	return buf;
}
void strbuf_free(StringBuffer *buf){
	if(buf != NULL){
	free(buf->contents);
	free(buf);
	}	
}

Recommended Answers

All 9 Replies

edit:

It's currently working if I use linux, but will not work on my windows OS.

anyone have a f

Well on the Linux box, you do this.

gcc -g prog.c
valgrind ./a.out

valgrind will tell you a lot about all kinds of memory abuse (overrun, use after free, uninitialised accesses etc).

When it is clean in valgrind, have another go on windows.

I've been debugging like crazy and I've come to the conclusion my problem at hand is

190: char *nString = (char*) malloc(sizeof(char));

any new help?

I ran the valgrind and I'm very unfamiliar with that program and how it works :S

I have under 12 hours to hand this is so I'm praying we can come to a conclusion

I've been debugging like crazy and I've come to the conclusion my problem at hand is

190: char *nString = (char*) malloc(sizeof(char));

That line only allocates enough memory for a single character. Is that what you want?

I believe so, the printout for executing that line should result in ""

regardless of how much space its allocating it just won't run/

I've run tests throughout my whole program, and it stops right when hitting that line.

I just tested the program as given above, using Code::Blocks 10.05 for Windows/GCC 4.4.1, and it compiled and ran smoothly. Oddly enough, it was in Linux that I had trouble - the "ansidecl.h" header file wasn't recognized, and the manual declarations of malloc() and memcpy() also presented problems, though once I removed those it once again ran fine.

I think I've solved the problem; you need to add an additional space for the zero delimiter each time you malloc() or realloc(), as the sizes you are using do not take the extra character into account.

Mind you, there is still some leaking memory, and at one point malloc() is being invoked with an argument of -4 (not sure how that happened). Here are the altered functions:

char *strndup (const char *s, size_t n)
{
  char *result;
  size_t len = strlen (s);

  if (n < len)
    len = n;

  result = (char *) malloc (len + 1);
  if (!result)
    return 0;

  result[len] = '\0';
  return (char *) memcpy (result, s, len);
}


StringBuffer *strbuf_new(const char *cstr){
	StringBuffer *strbuf = (StringBuffer*) malloc(sizeof(StringBuffer));
	if(strbuf == NULL){
		return NULL;
	}
	else{
		if(cstr != NULL){
			char *string = (char*) malloc(sizeof(char) * (strlen(cstr) + 1));
			if(string == NULL){
				return NULL;
			}
			else{
				strcpy(string,cstr);
				strbuf->contents = string;
				strbuf->length = strlen(string);
			}
		}
		else{
			char *NULLString = (char*) malloc(1);
			if(NULLString == NULL){
				return NULL;
			}
			else{
				strbuf->contents = NULLString;
				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 *newString = (char*) realloc(buf->contents, buf->length + strlen(cstr) + 1);
		if (newString == NULL){
			return NULL;
		}
		else {
		    if (buf->contents != newString) {   // in the case where the buffer got moved
                free(buf->contents);
                buf->contents = newString;
		    }
			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 *newString = (char*) realloc(buf->contents, buf->length + strlen(cstr) + 1);
                char *tempString = (char*) malloc(buf->length - pos + 1); //Temporary variable to store intermediate string value
                if (newString == NULL)
                        return NULL;
                else {
                        if(pos >= buf->length){
                                buf->contents = newString;
                                strcat(buf->contents, cstr);
                                buf->length = strlen(buf->contents);
                        }
                        else{
                                buf->contents = newString;
                                tempString = 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, tempString);    //Adding back the last part of the original string
                                buf->length = strlen(buf->contents);
                        }
                }
        }
        return buf;
}


StringBuffer *strbuf_reset(StringBuffer *buf, const char *cstr){
	if(buf == NULL){
		return NULL;
	}
	if(cstr == NULL){
		char *newString = (char*) malloc(1);

		if(newString == NULL){
			return NULL;
		}
		else{
			buf->contents = newString;
			strcpy(buf->contents,"");
			buf->length = strlen(buf->contents);
		}
	}
	else{
		char *newString = (char*) realloc(buf->contents, strlen(cstr) + 1);

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

Schoil-R-LEA, you are a life saver.

Thanks to everyone for the help, I'll be sure to try my best to help the community aswell.

cheers!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.