how to write data within malloc memory in C - malloc

Suppose I have
void * space= malloc(500) //alloc a block of memory
and I need to write two strings and an int: "Hello world", "Goodbye friend",5 in memory address 50,150,380, correspondance to space.I tried the approach:
int * insert = (int *)(space +380);
*insert = 5;
char * insert2 = (char *)(space+50);
*insert2 = "Hello world";
char * insert3 = (char *)(space + 150);
strcpy(insert3,"Goodbye friend");
the int has no problem, but the two string throws error messages. so what's the correct method to do this? Also, how can you check if there is an overlap in memory between those inputs (the string inputed can be arbitarily long?

Looking at this, I'm pretty sure that you trying to store "H" (which is a constant in C) that is of type int into insert2. In other words, your trying to store a type int (sizeof("H") == 2 on my compiler) into a char (sizeof(char) == 1). From there, it is up to your compiler to allow this behavior or throw an error. Plus "Hello world" is an immutable string that is located only in ROM, so you can't directly modified the string anyways.
To demonstrate, I ran:
printf("val:%d\n", "H");
printf("val:%d\n", "He");
printf("val:%d\n", "He");\\note 2nd instance the same
printf("val:%d\n", "Hel");
printf("val:%d\n", "Hell");
printf("val:%d\n", "Hello");
printf("val:%d\n", "Hello ");
printf("val:%d\n", "Hello W");
printf("val:%d\n", "Hello Wo");
printf("val:%d\n", "Hello Wor");
printf("val:%d\n", "Hello Worl");
printf("val:%d\n", "Hello World");
Yields:
val:4196404
val:4196406
val:4196406\\note 2nd instance the same
val:4196409
val:4196413
val:4196418
val:4196424
val:4196431
val:4196439
val:4196448
val:4196458
val:4196469
As #Rasmus was saying:
char * insert2 = (char *)(space+50);
strcpy(insert2 , "Hello world\0");// the '\0' if changing strings
Should resolve the issue.
BUT, I do not see much practical use for this, besides being vague/indecipherable, and not to mention wasteful of memory (unless you calculate it all out), so I recommend just using a struct:
struct blockOfMem{
int num;
char* str1;
char* str2;
};
....
struct blockOfMem space;
space.num = 5;
strcpy(space.str1, "Hello world\0");// the '\0' if changing strings
strcpy(space.str2, "Goodbye friend\0");// the '\0' if changing strings
This makes you code much more readable and practical to use.

Firstly, using strcpy i could make your code compile.
void * space= malloc(500); //alloc a block of memory
int * insert = (int *)(space +380);
*insert = 5;
char * insert2 = (char *)(space+50);
strcpy(insert2 , "Hello world");
char * insert3 = (char *)(space + 150);
strcpy(insert3,"Goodbye friend");
I would use strlen to get the length of the string and then sizeof(char). To get how much to allocate:
malloc(sizeof(int)+sizeof(char)*(1+strlen(string1))); // 1+ since you need to count the \0.
http://www.cplusplus.com/reference/cstring/strlen/

Related

How to store Integers from a string without using the getline function. C++

Sorry to ask, but I been looking everywhere to find a way to extract the integers from this set of strings:
{(1,2),(1,5),(2,1),(2,3),(3,2),(3,4),(4,3),(4,5),(5,1),(5,4)}
I don't really need the homework done, if you could link me to an example, I'll appreciate it.
thank you in advanced.
If you just want to access the integers from a line like that, one way is to simply continue reading integers while you can.
If, for some reason, you find an integer read failing (because there's a { in the input stream, for example), just skip over that single character and keep going.
Sample code for this is:
#include <iostream>
int main() {
int intVal; // for getting int
char charVal; // for skipping chars
while (true) {
while (! (std::cin >> intVal)) { // while no integer available
std::cin.clear(); // clear fail bit and
if (! (std::cin >> charVal)) { // skip the offending char.
return 0; // if no char left, end of file.
}
}
std::cout << intVal << '\n'; // print int and carry on
}
return 0;
}
A transcript follows:
pax> echo '{(314159,271828),(42,-1)}' | ./testprog
314159
271828
42
-1

How to measure memory consumption of DXL script?

Finding out if your script has a significant memory leak might be of interest even before you run into serious trouble. Unfortunately, I was not able to find out how to measure the current stack/heap size or "string table" size (see http://www.smartdxl.com/content/?p=481). Can anybody help?
Related question: Predicting DXL Memory and CPU Usage
The biggest memory "leak" would be open modules that are no longer being used. So of course you should be closing those.
Next you want to keep the production of new strings to a minimum since each new one creates an entry in a string table. You can find an excellent dissertation on that by Mathias Mamsch here: https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014886977&ps=25
Finally, data types that have create/delete methods can eat up memory if they are not being deleted. To find unreleased instances, I use some memory functions originally created by Mathias Mamsch. The link I have back to his post no longer works, but here are the functions that I use:
//< Memory Functions [Memory.inc]
/*
Code adapted from forum post by Mathias Mamsch:
https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014830975
*/
int *::+(int *ptr, int ofs)
{
int *rtn = ptr
rtn += ofs
return(rtn)
}
int *::#(int *ptr, int ofs)
{
int adr = *(ptr + ofs)
int *rtn = addr_(adr)
return(rtn)
}
int *mbn(int *ptr)
{
return(ptr # 0x74)
}
int *nnn(int *ptr)
{
return(ptr # 8)
}
int *ccp()
{
DB db = create("")
int *ptr = addr_(db)
int *rtn = ptr # 48
destroy(db)
return(rtn)
}
int allocatedObjects()
{
int cnt = 0
int *mb = mbn(ccp())
while(!null mb) { mb = nnn(mb) ; cnt++ }
return(cnt)
}
I'm pretty sure I changed the function and variable names from the original posted code, so be aware of that if you ever come across his original code. And don't ask me about the hard-coded numbers... Mathias explained them in the post and I don't recall the explanation.
Here's how you would use the code:
//< Test of Memory.inc
/*
*/
pragma encoding, "UTF-8"
#include <stdlib/Memory.inc>
pragma runLim, 0
int numallobj = allocatedObjects()
print numallobj "\n"
Skip skp = null Skip
numallobj = allocatedObjects()
print numallobj "\n"
skp = create()
numallobj = allocatedObjects()
print numallobj "\n"
delete(skp)
numallobj = allocatedObjects()
print numallobj "\n"
/*
Output should be:
0
0
1
0
*/
I found a solution for the "string table" part of the question. Mathias Mamsch provides a file "stringTable.inc" at https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014886977 which defines the function printStringTable(). Apparently, it outputs information about the table size and can be easily patched to provide an approximation of the string table bytesize.

Converting an int or String to a char array on Arduino

I am getting an int value from one of the analog pins on my Arduino. How do I concatenate this to a String and then convert the String to a char[]?
It was suggested that I try char msg[] = myString.getChars();, but I am receiving a message that getChars does not exist.
To convert and append an integer, use operator += (or member function concat):
String stringOne = "A long integer: ";
stringOne += 123456789;
To get the string as type char[], use toCharArray():
char charBuf[50];
stringOne.toCharArray(charBuf, 50)
In the example, there is only space for 49 characters (presuming it is terminated by null). You may want to make the size dynamic.
Overhead
The cost of bringing in String (it is not included if not used anywhere in the sketch), is approximately 1212 bytes of program memory (flash) and 48 bytes RAM.
This was measured using Arduino IDE version 1.8.10 (2019-09-13) for an Arduino Leonardo sketch.
Risk
There must be sufficient free RAM available. Otherwise, the result may be lockup/freeze of the application or other strange behaviour (UB).
Just as a reference, below is an example of how to convert between String and char[] with a dynamic length -
// Define
String str = "This is my string";
// Length (with one extra character for the null terminator)
int str_len = str.length() + 1;
// Prepare the character array (the buffer)
char char_array[str_len];
// Copy it over
str.toCharArray(char_array, str_len);
Yes, this is painfully obtuse for something as simple as a type conversion, but somehow it's the easiest way.
You can convert it to char* if you don't need a modifiable string by using:
(char*) yourString.c_str();
This would be very useful when you want to publish a String variable via MQTT in arduino.
None of that stuff worked. Here's a much simpler way .. the label str is the pointer to what IS an array...
String str = String(yourNumber, DEC); // Obviously .. get your int or byte into the string
str = str + '\r' + '\n'; // Add the required carriage return, optional line feed
byte str_len = str.length();
// Get the length of the whole lot .. C will kindly
// place a null at the end of the string which makes
// it by default an array[].
// The [0] element is the highest digit... so we
// have a separate place counter for the array...
byte arrayPointer = 0;
while (str_len)
{
// I was outputting the digits to the TX buffer
if ((UCSR0A & (1<<UDRE0))) // Is the TX buffer empty?
{
UDR0 = str[arrayPointer];
--str_len;
++arrayPointer;
}
}
With all the answers here, I'm surprised no one has brought up using itoa already built in.
It inserts the string representation of the integer into the given pointer.
int a = 4625;
char cStr[5]; // number of digits + 1 for null terminator
itoa(a, cStr, 10); // int value, pointer to string, base number
Or if you're unsure of the length of the string:
int b = 80085;
int len = String(b).length();
char cStr[len + 1]; // String.length() does not include the null terminator
itoa(b, cStr, 10); // or you could use String(b).toCharArray(cStr, len);

Parsing a string with varying number of whitespace characters in C

I'm pretty new to C, and trying to write a function that will parse a string such as:
"This (5 spaces here) is (1 space
here) a (2 spaces here) string."
The function header would have a pointer to the string passed in such as:
bool Class::Parse( unsigned char* string )
In the end I'd like to parse each word regardless of the number of spaces between words, and store the words in a dynamic array.
Forgive the silly questions...
But what would be the most efficient way to do this if I am iterating over each character? Is that how strings are stored? So if I was to start iterating with:
while ( (*string) != '\0' ) {
--print *string here--
}
Would that be printing out
T
h
i... etc?
Thank you very much for any help you can provide.
from http://www.cplusplus.com/reference/clibrary/cstring/strtok/
/* strtok example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-"); /* split the string on these delimiters into "tokens" */
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-"); /* split the string on these delimiters into "tokens" */
}
return 0;
}
Splitting string "- This, a sample string." into tokens:
This
a
sample
string
First of all, C does not have classes, so in a C program you would probably define your function with a prototype more like one of the following:
char ** my_prog_parse(char * string) {
/* (returns a malloc'd array of pointers into the original string, which has had
* \0 added throughout ) */
char ** my_prog_parse(const char * string) {
/* (returns a malloc'd NULL-terminated array of pointers to malloc'd strings) */
void my_prog_parse(const char * string, char buf, size_t bufsiz,
char ** strings, size_t nstrings)
/* builds a NULL-terminated array of pointers into buf, all memory
provided by caller) */
However, it is perfectly possible to use C-style strings in C++...
You could write your loop as
while (*string) { ... ; string++; }
and it will compile to exactly the same assembler on a modern optimizing compiler. yes, that is a correct way to iterate through a C-style string.
Take a look at the functions strtok, strchr, strstr, and strspn... one of them may help you build a solution.
I wouldn't do any non-trivial parsing in C, it's too laborious, the language is not suitable for that. But if you mean C++, and it looks like you do, since you wrote Class::Parse, then writing recursive descent parsers is pretty easy, and you don't need to reinvent the wheel. You can take Spirit for example, or AXE, if you compiler supports C++0x. For example, your parser in AXE can be written in few lines:
// assuming you have 0-terminated string
bool Class::Parse(const char* str)
{
auto space = r_lit(' ');
auto string_rule = "This" & r_many(space, 5) & space & 'a' & r_many(space, 2)
& "string" & r_end();
return string_rule(str, str + strlen(str)).matched;
}

VC++ read variable length char*

I'm trying to read a variable length char* from the user input. I want to be able to specify the length of the string to read when the function is called;
char *get_char(char *message, unsigned int size) {
bool correct = false;
char *value = (char*)calloc(size+1, sizeof(char));
cout << message;
while(!correct) {
int control = scanf_s("%s", value);
if (control == 1)
correct = true;
else
cout << "Enter a correct value!" <<endl
<< message;
while(cin.get() != '\n');
}
return value;
}
So, upon running the program and trying to enter a string, I get a memory access violation, so I figured something has gone wrong when accessing the allocated space. My first idea was it went wrong because the size of the scanned char * is not specified within scanf(), but it doesn't work with correct length strings either. Even if I give the calloc a size of 1000 and try to enter one character, the program crashes.
What did I do wrong?
You have to specify the size of value to scanf_s:
int control = scanf_s("%s", value, size);
does the trick.
See the documentation of scanf_s for an example of how to use the function:
Unlike scanf and wscanf, scanf_s and wscanf_s require the buffer size to be specified for all input parameters of type c, C, s, S, or [. The buffer size is passed as an additional parameter immediately following the pointer to the buffer or variable.
I omit the rest of the MSDN description here because in the example they're providing, they use scanf instead of scanf_s what is quite irritating...

Resources