_snwprintf_s heap corruption error in free() call - c

I am trying to use _snwprintf_s to concatenate two strings. I also want to append \r\n after each string.
So I allocate a wchar buffer initially including the \r\n and null for both strings. I try to print one after the other.
I see both strings are written. But when trying to free(wbuff), it throws me a "Heap corruption" error. I am not able to figure where I am crossing the bounds.
Where am I going wrong? Let me know. Thanks
int main()
{
WCHAR* name1 = L"HelloWorld";
WCHAR* name2 = L"GoodMorning";
WCHAR* wbuff = NULL;
int i = wcslen(name1) + wcslen(name2) + 6; //in words for size of buffer
int out = 0;
wbuff = (WCHAR*)malloc(i * sizeof(WCHAR));
ZeroMemory(wbuff, i * sizeof(WCHAR));
int prevLen = 0, currLen = 0;
currLen = wcslen(name1) + 2; //in bytes
out = _snwprintf_s(wbuff,i,currLen, L"%s\r\n", name1);
printf("Wrote %d characters\n", out);
prevLen = currLen;
currLen = wcslen(name2) + 2;
out = _snwprintf_s((wbuff+prevLen),i,currLen, L"%s\r\n", name2);
printf("Wrote %d characters\n", out);
printf("%S of sisze %u", wbuff, wcslen(wbuff));
free(wbuff);
printf("memory freed\n");
}

_snwprintf_s fills up the remaining characters in the buffer with an fefe marker. I can't find this in the documentation, but I can see it in the debugger. Hence, your second _snwprintf_s is indicating it's got i characters available, but your start position is prevLen chars into it. Fix i to have the offset adjustment as well.
Instead of this:
out = _snwprintf_s((wbuff+prevLen),i,currLen, L"%s\r\n", name2);
This:
out = _snwprintf_s((wbuff+prevLen),i-prevLen,currLen, L"%s\r\n", name2);
_snwprintf_s will fill up the entire buffer with markers
Instead of this:
printf("%S of sisze %u", wbuff, wcslen(wbuff));
This:
printf("%ls of sisze %u", wbuff, (unsigned int)(wcslen(wbuff)));

Related

add \0 in the middle of char pointer

I have a bigger string and I want to add the \0 character before a specific string is contained.
ex:
inputString = "some2.text.here"; => outputText = "some2";
I manage to find the last position of the output text, I don't know how to add \0 and make the pointer end here.
void test()
{
char* str = "some2.text.here";
char* search = ".text.here";
char * new;
//size text to be removed
int lengthOfStr = 10; //search length
int size = 0;
char stringEnding = '\0';
char * newPath;
new = '\0';
for(int i = 0; i < 200; i++){
if(*(str + i) == '\0'){
printf("found on index %d", i);
printf("\n i: %d \n lengthOfStr : %d", i, lengthOfStr);
new = (char *) malloc(i - lengthOfStr);
memcpy(new, str, sizeof(i - lengthOfStr));
break;
}
}
printf("\n string value : %s", new);
}
Here I try to copy a specific length but is not working well... I also tried to add str[5] = '\0'but also did not did the trick... Any tips?
There seems to be 3 problems.
Too little memory allocated
Wrong number of bytes copied
Missing string termination
Something like:
new = malloc(i - lengthOfStr + 1); // Allocate 1 more char
memcpy(new, str, i - lengthOfStr); // Correct number of bytes to copy
new[i - lengthOfStr] = '\0'; // Terminate the string
BTW: Your current code always expects the "search" string to be in the end of the current string. Maybe that's what you want but it seems to me that you should use strstr instead of a loop. And... use strlen instead of a hard code length.

Stripping a sentence for only it's alpha characters

I'm trying to solve a code to strip a sentence down only to it's alpha character, using the following code, but the code always gives me a runtime error(The commented parts are steps I had taken to figure out the solution).
[Ex: Test'sen- tence should print Testsentence]
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define BUFFER_LEN 1000
#define BUFFER_INCR 15
int main(void)
{
int buffer_length = BUFFER_LEN;
char *pString = malloc(BUFFER_LEN);/* initial array */
char *pTemp_start = pString;
long long int String_len = 0;
char *pTemp = NULL;
int copy = 0;
int count = 0;/*delete this after check*/
while((*pString++ = getchar()) != '\n')
{
String_len = pString - pTemp_start;
printf("\nThe character you inputted is: %c", *(pString+count++));
//getchar();
if(String_len == (buffer_length - 1))/*reserve one for newline*/
{
buffer_length += BUFFER_INCR;
pTemp = realloc(pString, buffer_length);/*reallocate space for
15 more chars.*/
pTemp_start = pTemp - String_len;
pString = pTemp;
free(pTemp);
pTemp = NULL;
if(!pString)
{
printf("The space couldn't be allocated");
return 1;
}
}
}
/*checks that can be done for addresses*/
//printf("\nThe length of the string is: %lld", pString - pTemp_start);
*(--pString) = '\0';
//printf("\nThe charcter at the end is: %d", *(pString + String_len - 1));
//printf("\nThe character at the mid is: %d", *(pString + 2));
printf("The input string is: %c", *pString);
/*code to remove spaces*/
for(int i = 0; i < (String_len + 1); i++)
{
if((isalnum(pString[i])))
{
*(pString + copy++) = *(pString +i);
}
}
*(pString + copy) = '\0';/*append the string's lost null character*/
printf("\nThe stripped string is: \n%s", pString);
return 0;
}
The code simply doesn't print anything that's inputted.
So you've got a conflict in your code between this line
while((*pString++ = getchar()) != '\n')
and lines like the following.
pTemp = realloc(pString, buffer_length);
The first line I've quoted is incrementing the position of pString within your allocated memory, but the second one is acting as if pString is still pointing to the start of it. realloc() won't work unless pString is pointing to the start of the allocated memory. You're then not checking the results of the realloc() call, assigning the new memory block to pString and then freeing the newly allocated memory. So you're definitely going to have unexpected results.
You also have to remember that stdin is buffered, so your code will wait until it's got an entire line to read before doing anything. And stdout is also buffered, so only lines that end in a \n will be output. So you probably want to have the following...
printf("The character you inputted is: %c\n", *pString);
...or something similar bearing in mind the issues with how you're using pString.
realloc(pString,...) does not add an allocated block, it replaces the one being reallocated (in this case, pString). So pString isn't (necessarily) a valid pointer after that call. Worse, you then free(pTemp), so you no longer have anything allocated.

split string and store it in different variable in C

I want to split this string
kim-tae-yeon
and put them into different variables, like this:
data[1] = "kim" data[2] = "tae" data[3] = "yeon"
but I only split the string without store them to these variable.
How can I do this?
Here is my code:
char buff[] = "kim-tae-yeon";
int i = 0;
char *p = strtok (buff, "-");
char *data[3];
while (p)
{
data[i++] = p;
p = strtok (NULL, "-");
}
for (i = 0; i < 3; i++)
{
printf ("%s\n", &data[i]);
}
return 0;
}
Your program works well. The error comes by the fact that you are passing to printf &data[i] but datais an array of pointers (char *[]), which means each entry of the array is a pointer (char *). You want pass to printf a string, data[i].
This is the output you want:
for (i = 0; i < 3; i++)
{
printf("data[%i] = %s\n", i+1, data[i]);
}
As in the comment were said, there is no data[3].
The array starts at data[0], this is a default of C.
You can still have the output
data[1] = kim
data[2] = tae
data[3] = yaeon
by adding 1 to i,
but this output doesn't represent your actual data array.
This is wrong:
printf("%s\n", &data[i]);
The %sformat specifier requires a char* but you provided a char **(pointer to pointer to char). data[i] is already a char *, therefore you need:
printf("%s\n", data[i]);
If you had compiled with all warnings enabled (-Wall option with gcc) your compile would have told you this.
If you're ready to limit the length of the substrings, this can be solved much easier and less scary (strtok() is scary, come on!) using plain old sscanf():
const char buff[] = "kim-tae-yeon";
char data[3][32];
if (sscanf(buff, "%31[^-]-%31[^-]-%31[^-]", data[0], data[1], data[2]) == 3)
{
printf("parts are '%s', '%s' and '%s'\n", data[0], data[1], data[2]);
}
The format specifier, which is repeated three times with dashes in-between, is %31[^-], this means "collect at most 31 non-dash characters". The 31 makes sure there's room to terminate in our 32-character buffers.
It's a bit non-DRY with the buffer size repeated in the format string, the easiest fix for this is to generate the format string at run-time using snprintf(), but that obscures the issue so I didn't do that.
Something like this can work. It instead uses strcpy to copy over the string being pointed at, in this case buffer, to the space in data[i].
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STRSIZE 50
#define NUMWORDS 3
int
main(void) {
char buff[] = "kim-tae-yeon";
char data[NUMWORDS][STRSIZE];
char *buffer;
int i;
buffer = strtok(buff, "-");
i = 0;
while (buffer != NULL) {
strcpy(data[i], buffer);
printf("data[%i] = %s\n", i+1, data[i]);
buffer = strtok(NULL, "-");
i++;
}
return 0;
}

Filter one buffer and copy it into another C

I'm trying to read a buffer, copy all the non-alphabetical characters and dump it into another buffer.
The problem I'm getting is that whenever I encounter a non numerical character, it won't copy anything more.
I have tried to try to detect the blank spaces, use an auxiliary buffer...
int main(void)
{
char buffer[] = "103 PLUS 1";
char buffer2[] = "a";
int i, number;
memset(buffer2, 0, sizeof (buffer2));
size_t length = strlen(buffer);
fprintf(stdout,"Buffer initially: %s \n", buffer);
fprintf(stdout,"Buffer2 initially: %s \n", buffer2);
for(i=0; i<length; i++)
{
if (number = isalpha(buffer[i]) == 0)
{
strncpy(&buffer2[i], &buffer[i], 1);
}
}
fprintf(stdout, "Copied buffer is: %s \n", buffer2);
return 0;
}
Thanks in advance.
Your code leaves the first element of buffer2 to be 0, indicating the end of the C-string. In fact, the index of same characters should differ in buffer and buffer2, because characters must be consistent within a C-string, but some characters are not copied.
It's unnecessary to initialise buffer with "a". Use {0} instead.
You don't need to use variable number.
Refined code:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void)
{
char buffer[80] = "103 PLUS 1";
char buffer2[80] = {0};
int i, j = 0;
size_t length = strlen(buffer);
fprintf(stdout,"Buffer initially: %s \n", buffer);
fprintf(stdout,"Buffer2 initially: %s \n", buffer2);
for(i = 0; i < length; i++)
{
if (isalpha(buffer[i]))
{
strncpy(&buffer2[j++], &buffer[i], 1);
}
}
fprintf(stdout, "Copied buffer is: %s \n", buffer2);
return 0;
}
Output:
Buffer initially: 103 PLUS 1
Buffer2 initially:
Copied buffer is: PLUS
When you skip copying a character over, buffer2 is left w/ whatever was originally in that position, which seems to be 0 (but may not always be), which is why printing it out looks like no other characters were copied. In fact, they were, but the skipped character is interpreted as the null termination of that string.
But worse, you never allocate space for buffer2: you let the compiler do it, which means you aren't really allowed to modify that space. As with the above, you might be getting away with it, but it is undefined behavior, and could actually crash your program.

Working with Char in c programming

I am a newbie in c programming language and I have a university tutorial assignment that is related with working with chars(I wont be graded for this assignment) where you have to count words, I have to compile and submit my answers in an online web environment where my code will run against test cases that are not visible to me.here is my assignment:
Write the function 'wc' which returns a string containing formatted as follows: "NUMLINES NUMWORDS NUMCHARS NUMBYTES" .
Whitespace characters are blanks, tabs (\t) and new lines (\n). A character is anything that is not whitespace. The given string is null-char (\0) terminated.
here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* wc(char* data) {
char* result ;
int numLine ;
int numWords ;
int numChars ;
int i;
int numBytes =strlen(data);
char* empty=NULL;
while(strstr(data,empty)>0){
numWords=1;
for (i = 0; i < sizeof(data); i++) {
if(data[i]=='\n'){
numLine++;
}
if(data[i]==' ' ){
numWords++;
}
if(data[i]!=' '){
numChars++;
}
}
}
sprintf(result, "%d %d %d %d", numLine, numWords, numChars, numBytes);
return result;
}
this code will give me the correct output result but I am missing something here at least the test tells me that.
You've got a very serious error:
char* result;
...
sprintf(result, "%d %d %d %d", numLine, numWords, numChars, numBytes);
This is not allowed in C. You need to allocate sufficient memory for the string first. Declare result as a large enough static array, or use malloc if you've covered that in your course.
e.g.
char buf[100]; // temporary buffer
sprintf(buf, "%d %d %d %d", numLine, numWords, numChars, numBytes);
char *result = malloc(strlen(buf) + 1); // just enough for the string
strcpy(result, buf); // store the string
return result;
What if you have this input?
Two Words.
You have to count the transitions between whitespace/non-whitespace, not just count spaces.
Also, I'm pretty sure strstr(data,NULL) will not do anything useful.
You also appear to be missing the \t for tab in your white space checker, and you're not correctly checking when you're in or out of a word. You can use the boolean type bool for this defined in stdbool.h for this.
Source code of wc unix command:
http://www.gnu.org/software/cflow/manual/html_node/Source-of-wc-command.html
All test cases handled.
1) sizeof is wrong:
Instead of sizeof operator you need to use strlen() in for loop, like:
for (i = 0; i < strlen(data); i++)
^ not sizeof
sizeof(data) returns only size of data pointer address that is 4. Because you are to read all char in data[] you need strlen() that will return length of data[] (or number of chars in data[])
2) memory error:
Next Error I can notice there is no memory allocated for result. it declare like:
char* result ;
and No memory allocate! and you are writing using sprintf that cause undefined behavior of your code
3) while(strstr(data,empty)>0) is wrong
strstr() search position of a string in to other you empty string is NULL , CHECK:
char *strstr(const char *s1, const char *s2);
you strstr() always returns data, Why are you calling this? I believe you don't need this while() loop.
I improved you code upto some extend as below, There was only three error as I mentioned above now corrected(to understand read comments), You basic algo is correct:
#define SIZE 256 // added size macro
char* wc(char* data)
char* result = malloc(SIZE*sizeof(char)); //(2) allocated memory for result
int numLine ;
int numWords ;
int numChars ;
int i;
int numBytes =strlen(data);
numWords=1;
// (3) remove while loop
for (i = 0; i < strlen(data); i++) { //(1) change size
if(data[i]=='\n'){
numLine++;
}
if(data[i]==' ' ){
numWords++;
}
if(data[i]!=' '){
numChars++;
}
}
sprintf(result, "%d %d %d %d", numLine, numWords, numChars, numBytes);
return result;
}
int main(){
printf("\nresult: %s\n", wc("q toei lxlckmc \t \n ldklkjjls \n i \t nn "));
return 1;
}
Output:
result: 2 14 28 41

Resources