2

i wrote this function, which read strings char by char and increase the allocated size. for some reason im getting randomly the error " _CrtIsValidHeapPointer" in VS2010, while reading strings with around 100+ chars. i tried to debug it, but i really cant figure whats wrong

char *unknown_size_string(){
    int i=0, size=10;
    char *name=NULL, *alloc_check=NULL, letter;
    //allocates initial size of 10 bytes
    name=(char *)malloc(sizeof(char)*size);
    if(!name){return NULL;}
    //reads char by char until newline reached
    while((letter=getchar())!='\n'){
        *((name)+i++)=letter;
        //when the remaining buffer size is 1 byte, allocating another 10 bytes
        if((i+1)==size){
            alloc_check=name;
            realloc(alloc_check,(size+=10)*sizeof(char));
            if(!alloc_check){return name;}
            name=alloc_check;
        }
    }
    *((name)+i)='\0';
    return name;
}

any help would be appreciated.

thanks

6
  • 1
    The last *((name)+i='\0'; could result in an error if string had exact length of 10 chars, you will not realloc it, then add '\0' at the eleventh position (i = 10)... Or maybe I'm wrong Commented Feb 10, 2017 at 10:13
  • I think i have it covered by allocation when 1 byte left, but ill try to see if it changes something Commented Feb 10, 2017 at 10:15
  • @MartinVerjans You're right. The check should be done accounting for the end null space. Commented Feb 10, 2017 at 10:15
  • 1
    There should be no byte left because addressing starts with 0th element (when you check for i+1, with i=9, you have just assigned the 10th element). Commented Feb 10, 2017 at 10:16
  • you might be interested in getline, which does what you're trying to do, but probably more efficiently. Note that this function is not part of the base standard, but of an extension. Read the linked reference page for more details. Commented Feb 10, 2017 at 10:24

1 Answer 1

3

Aside from the comments about taking into account null-termination byte, the main problem here is:

realloc returns the new allocated area (which may be the same, may be not).

So you have to assign back alloc_check in realloc(alloc_check,(size+=10)*sizeof(char)); or you just create a memory leak and keep writing in an old location.

alloc_check = realloc(alloc_check,(size+=10));

(well, when the size is greater, the location isn't guaranteed to change everytime, but it has to sometimes when there's not enough contiguous space)

Aside: name=(char *)malloc(sizeof(char)*size); => name=malloc(size); (size of char is always 1, and no need to cast malloc pointer)

Extract from N5170:

When sizeof is applied to an operand that has type char,unsigned char,or signed char, (or a qualified version thereof) the result is 1.

Sign up to request clarification or add additional context in comments.

6 Comments

You're right +1. But not for sizeof(char), it can be !=1 (i.e. on EBCD system) ;). C standards doesn't specify it.
@Frankie_C thanks for the UV. I've read sizeof(char)==1 several times here, will check: found it: stackoverflow.com/questions/40679801/…
@Frankie_C : sizeof(char) is guaranteed to be 1 by the C standard. It's just not guaranteed that that 1 corresponds to an 8-bit byte (refer to CHAR_BIT).
from my understanding in vs2010 even in *.c files the c++ compiler is used, and you must csst the malloc. I will do what you suggested when im near my code later.
@hellazari No, Visual Studio compiles files with a .c extension as C code, not C++.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.