I have a simple program and I get access violation at *(str + start). Why? I should be able to change it. Right?
void fn()
{
char *str = "Hello wordl!";
int end = strlen(str);
int start = 0;
end--;
while(start < end)
{
*(str + start) = *(str + end); <--- Access violation writing location *(str + Start).
end--;
start++;
}
}
char *str = "Hello World"; is a const string, and cannot be modified. The compiler is free to put it into a non-writable location, resulting in the crash you see.
Replacing the declaration with char str[] = "Hello World"; should do what you want, putting the string into a modifiable array on the stack.
No, you should not. "Hello world" is a constant string literal, you need to allocate memory using malloc() in C, or new in C++ if you want memory you are free to modify.
As others have pointed out, literal strings may be stored in a read-only area of memory. Are you compiling with warnings turned on? You should get a warning about discarding the constness of the string literal.
What you can do instead is:
char *str = strdup("Hello, world!");
// Modify the string however you want
free(str);
It's because you're writing to a string literal's storage, which may be in a protected area of memory.
In your example, Hello wordl! is constant string, any attempt to modify this constant string will result in an exception.
Instead, You can do this -
string s = "Hello wordl!";
char* ptr = &s[0];
and then play around with ptr.
Related
making an assignment and had to dynamically allocate an array of pointers and then free it at the end of the function.
the problem is when I free the array, it gives me a "Heap Corruption Detected" error and i cant figure out why that happens.
can anybody see something here ?
it says im writing after the end of allocated memory but i cant see why.
typedef struct _client
{
char id[9];
char phone[12];
} Client;
Short_client *createShortClientArr(int n)
{
Client *arr = (Client *)malloc(n * sizeof(Client));
char garbage;
garbage = getc(stdin);//for getting the '\n' from the last input
for (int i = 0; i < n; i++)
{
fgets(arr[i].id, 9, stdin);
arr[i].id[9] = '\0';
garbage = getc(stdin);
fgets(arr[i].phone, 12, stdin);
arr[i].phone[12] = '\0';
garbage = getc(stdin);
}
free(arr);
}
When you free memory, Windows will also check and see if you'd written past the end of the array. Since you did, it throws this exception, to let you know you have a bug.
char phone[12];
This creates an array whose indecies are 0-11.
arr[i].phone[12] = '\0';
12 is not a valid index for this array, and so this writes a '\0' to the char one past the end of the array. You have the same bug with your other array as well.
I'm writing some code to take in a string, turn it into a char array and then print back to the user (before passing to another function).
Currently the code works up to dat.toCharArray(DatTim,datsize); however, the pointer does not seem to be working as the wile loop never fires
String input = "Test String for Foo";
InputParse(input);
void InputParse (String dat)
//Write Data
datsize = dat.length()+1;
const char DatTim[datsize];
dat.toCharArray(DatTim,datsize);
//Debug print back
for(int i=0;i<datsize;i++)
{
Serial.write(DatTim[i]);
}
Serial.println();
//Debug pointer print back
const char *b;
b=*DatTim;
while (*b)
{
Serial.print(*b);
b++;
}
Foo(*DatTim);
I can't figure out the difference between what I have above vs the template code provided by Majenko
void PrintString(const char *str)
{
const char *p;
p = str;
while (*p)
{
Serial.print(*p);
p++;
}
}
The expression *DatTim is the same as DatTim[0], i.e. it gets the first character in the array and then assigns it to the pointer b (something the compiler should have warned you about).
Arrays naturally decays to pointers to their first element, that is DatTim is equal to &DatTim[0].
The simple solution is to simply do
const char *b = DatTim;
This was the original code
int main(void)
{
char hello[] = "hello ", world[] = "world!\n", *s;
s = strcat(hello,world);
printf(s);
return 0;
}
char hello[] = "hello ", world[] = "world!\n", *s;
strcat(hello,world);
printf(hello);
i changed it to what it is below
i am positive i fixed that code, but my instructor marked me off.
like i told him it doesn't even use the pointer, so this is fine. he said he doesn't think it's correct
am i wrong?
like i ran it 50 times and it still works.
Your instructor is correct. hello is only big enough to hold 6 characters (plus a null-terminator). So trying to strcat something into it writes past the end, causing undefined behaviour.
I've got a form with a Listbox which contains lines of four words.
When I click on one line, these words should be seen in four different textboxes.
So far, I've got everything working, yet I have a problem with chars converting.
The string from the listbox is a UnicodeString but the strtok uses a char[].
The compiler tells me it "Cannot Convert UnicodeString to Char[]". This is the code I am using for this:
{
int a;
UnicodeString b;
char * pch;
int c;
a=DatabaseList->ItemIndex; //databaselist is the listbox
b=DatabaseList->Items->Strings[a];
char str[] = b; //This is the part that fails, telling its unicode and not char[].
pch = strtok (str," ");
c=1;
while (pch!=NULL)
{
if (c==1)
{
ServerAddress->Text=pch;
} else if (c==2)
{
DatabaseName->Text=pch;
} else if (c==3)
{
Username->Text=pch;
} else if (c==4)
{
Password->Text=pch;
}
pch = strtok (NULL, " ");
c=c+1;
}
}
I know my code doesn't look nice, pretty bad actually. I'm just learning some programming in C++.
How can I convert this?
strtok actually modifies your char array, so you will need to construct an array of characters you are allowed to modify. Referencing directly into the UnicodeString string will not work.
// first convert to AnsiString instead of Unicode.
AnsiString ansiB(b);
// allocate enough memory for your char array (and the null terminator)
char* str = new char[ansiB.Length()+1];
// copy the contents of the AnsiString into your char array
strcpy(str, ansiB.c_str());
// the rest of your code goes here
// remember to delete your char array when done
delete[] str;
This works for me and saves me converting to AnsiString
// Using a static buffer
#define MAX_SIZE 256
UnicodeString ustring = "Convert me";
char mbstring[MAX_SIZE];
wcstombs(mbstring,ustring.c_str(),MAX_SIZE);
// Using dynamic buffer
char *dmbstring;
dmbstring = new char[ustring.Length() + 1];
wcstombs(dmbstring,ustring.c_str(),ustring.Length() + 1);
// use dmbstring
delete dmbstring;
Why does the following code throw an exception when getting to the second scanf_s after entering an number to put into the struct.
This by no means represents a complete linked list implementation.
Not sure how to get onto the next scanf_s when having entered the value? Any ideas?
EDIT: Updated code with suggested solution, but still get an AccessViolationException after first scanf_s
Code:
struct node
{
char name[20];
int age;
float height;
node *nxt;
};
int FillInLinkedList(node* temp)
{
int result;
temp = new node;
printf("Please enter name of the person");
result = scanf_s("%s", temp->name);
printf("Please enter persons age");
result = scanf_s("%d", &temp->age); // Exception here...
printf("Please enter persons height");
result = scanf_s("%f", &temp->height);
temp->nxt = NULL;
if (result >0)
return 1;
else return 0;
}
// calling code
int main(array<System::String ^> ^args)
{
node temp;
FillInLinkedList(&temp);
...
You are using scanf_s with incorrect parameters. Take a look at the examples in the MSDN documentation for the function. It requires that you pass in the size of the buffer after the buffer for all string or character parameters. So
result = scanf_s("%s", temp->name);
should be:
result = scanf_s("%s", temp->name, 20);
The first call to scanf_s is reading garbage off the stack because it is looking for another parameter and possibly corrupting memory.
There is no compiler error because scanf_s uses a variable argument list - the function doesn't have a fixed number of parameters so the compiler has no idea what scanf_s is expecting.
You need
result = scanf_s("%d", &temp->age);
and
result = scanf_s("%f", &temp->height);
Reason is that sscanf (and friends) requires a pointer to the output variable so it can store the result there.
BTW, you have a similar problem with the parameter temp of your function. Since you're changing the pointer (and not just the contents of what it points to), you need to pass a double pointer so that the changes will be visible outside your function:
int FillInLinkedList(node** temp)
And then of course you'll have to make the necessary changes inside the function.
scanf() stores data into variables, so you need to pass the address of the variable (or its pointer)Example:
char string[10];
int n;
scanf("%s", string); //string actually points to address of
//first element of string array
scanf("%d", &n); // &n is the address of the variable 'n'
%19c should be %s
temp->age should be &temp-age
temp->height should be &temp->height
Your compiler should be warning you
about these errors
I believe you need to pass parameters to scanf() functions by address. i.e. &temp->age
otherwise temp-age will be interpreted as a pointer, which will most likely crash your program.