I'm trying to concatenate two strings so I can obtain a file path. However, I'm receiving an error in valgrind
Conditional jump or move depends on uninitialised value(s)
My code:
/**
* #brief Concatenate two strings to get file path
* #param firstP - First string
* #param secondP - Second string
* #return Returns the concatenated string
*/
char *getPathDir(char *firstP, char *secondP) {
char *new_str;
int stringSize = strlen(firstP)+strlen(secondP)+2;
if((new_str = malloc(stringSize)) != NULL){
new_str[0] = '\0';
strcat(new_str,firstP);
new_str[strlen(firstP)] = '/';
strcat(new_str,secondP);
} else {
perror("malloc");
cleanUp();
exit(EXIT_FAILURE);
}
return new_str;
}
Let's look at these lines:
new_str[0] = '\0';
strcat(new_str,firstP);
new_str[strlen(firstP)] = '/';
strcat(new_str,secondP);
Prior to writing anything, the string looks like this:
+---+---+---+---+---+---+---+---+
| ? | ? | ? | ? | ? | ? | ? | ? |
+---+---+---+---+---+---+---+---+
After the first line (new_str[0] = '\0';), you have this:
+---+---+---+---+---+---+---+---+
| 0 | ? | ? | ? | ? | ? | ? | ? |
+---+---+---+---+---+---+---+---+
After the second line (strcat(new_str,firstP);), it looks like this:
+---+---+---+---+---+---+---+---+
| A | B | C | D | 0 | ? | ? | ? |
+---+---+---+---+---+---+---+---+
Now, when you execute the line
new_str[strlen(firstP)] = '/';
you overwrite the null terminator and get this:
+---+---+---+---+---+---+---+---+
| A | B | C | D | / | ? | ? | ? |
+---+---+---+---+---+---+---+---+
This is a problem, because your string is no longer null-terminated, so when you next call strcat the program will start reading into uninitialized memory hunting around for a null terminator.
If you want to concatenate the strings together, it might be easier to just use sprintf, like this:
sprintf(new_str, "%s/%s", firstP, secondP);
This more explicitly says "write the first string, then the separator, then the second string" and offloads all the null terminator management to the library. And libraries, with the exception of strncat, typically handle null terminators pretty well. :-)
There's also a chance that the sprintf might be marginally faster than what you're doing. Using lots of strcats in a row in the way you're proposing can be inefficient due to the overhead of rescanning the strings to find the null terminators, but I wouldn't bet on it. It does, however, have the very clear advantage of more accurately communicating what it is that you're trying to do, and readability wins are rarely a bad thing.
Related
I am trying to understand the below code. But I am not getting it.
Basically, the below code currently checks for if condition in a c or cpp file.
if ($perl_version_ok &&
$line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
# Throw error
}
where Constant is any macro or any constant value; LvalOrFunc is any variable or function call; Compare is the operations like !=, == ,&& , etc
The if checks for codes like this if(CONST_VALUE == x), where CONST_VALUE is some macros. In this case its true and goes inside if condition.
But I want to check for the opposite if(x == CONST_VALUE ), and then throw error.
Please help in understanding this piece of line and how to achieve the desired result.
Note:
The code is from linux kernel dir, available here: https://github.com/torvalds/linux/blob/master/scripts/checkpatch.pl
Line number of the code: 5483
The code doesn't check for if(CONST_VALUE == x). As shown in the comments above the line in the source code
# comparisons with a constant or upper case identifier on the left
# avoid cases like "foo + BAR < baz"
# only fix matches surrounded by parentheses to avoid incorrect
# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
it checks for a plus sign followed by a CONSTANT_VALUE == x. The \+ in the regex matches a plus sign.
$line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/
^ ^ ^ ^ ^
| | | | |
binding | | | word
operator | | | boundary
start | |
of string | |
plus |
anything
Reverting the compared values should be easy:
($LvalOrFunc)\s*($Compare)\s*($Constant|[A-Z_][A-Z0-9_]*)
I'm trying to print text to an output file, and I need my output file to match the proper formatting exactly.
I need to do this so that when my program's output is compared to what the proper output should be, (talking large output files here) a simple string comparison of the output files should flag them as perfectly identical.
Here is an example of the EXACT expected output:
| Item 1234 | CALCULATOR | $ 0.45 |
| Item 5678 | USA_FLAG | $ 10.99 |
| Item 9012 | WITCH_BROOM | $ 18.00 |
Notice how with this formatting there are variable amounts of spaces after each string and before the double numbers, but they still manage to line up perfectly.
So how do you output this kind of formatting?
I'm assuming there is something about fprintf() that I just don't know, but again, I don't know soooooooooooooo
You can specify flags and width in the printf format string e.g.
printf( "%10s", "test" ) will print a 10 characters and pad with spaces if the argument is shorter. e.g (dots added for spaces)
test......
You can also specify justification e.g.
printf( "%-10s", "test" )
......test
This question already has answers here:
Find and Replace Inside a Text File from a Bash Command
(18 answers)
Closed 4 years ago.
This is output of the grep -E "scsi0:" *.vmx | grep -E "fileName" command in one of my directory:
scsi0:0.fileName = "vmname.vmdk"
scsi0:1.fileName = "vmname_1.vmdk"
scsi0:2.fileName = "vmname_2.vmdk"
scsi0:3.fileName = "P120_vmname_2.vmdk"
scsi0:4.fileName = "P120_vmname_3.vmdk"
I need to rewrite above output inside that vmx file so it looks like following
scsi0:0.fileName = "vmname.vmdk"
scsi0:1.fileName = "vmname_1.vmdk"
scsi0:2.fileName = "vmname_2.vmdk"
scsi0:3.fileName = "vmname_3.vmdk"
scsi0:4.fileName = "vmname_4.vmdk"
So in essence the script needs to the following:
look for the line which contains scsi0 and filename and remove everything after double quote before vmname
check what is the number in that line after "scsi0:" and add/replace that number after the underscore, so P120_vmname_2 becomes vmname_3
The thing is that there can by any number of characters before vmname which need to be removed and lines which need to be fixed can be anywhere in the source file.
Do I need to assign individual line output to separate variable or it is possible to manipulate them with just one?
Thanks
Could you pipe your grep output into sed?
If so, you could do a substitution like this:
sed -r 's/^(.*:)([[:digit:]]+)(.*) = \".*vmname_[[:digit:]]+/\1\2\3 = \"vmname_\2/'
# ^ ^ ^ ^ ^ ^ ^
# | | | | | | Replace number.
# | | | | | Re-create line start
# | | | | Match incorrect number
# | | | Match garbage before "vmname"
# | | Match Filename
# | Correct number
# Line start
So your actual command would look like this:
grep -E "scsi0:" *.vmx | grep -E "fileName" | \
sed -r 's/^(.*:)([[:digit:]]+)(.*) = \".*vmname_[[:digit:]]+/\1\2\3 = \"vmname_\2/'
Converts this:
scsi0:0.fileName = "vmname.vmdk"
scsi0:1.fileName = "vmname_1.vmdk"
scsi0:2.fileName = "vmname_2.vmdk"
scsi0:3.fileName = "P120_vmname_2.vmdk"
scsi0:4.fileName = "P120_vmname_3.vmdk"
scsi0:5.fileName = "P12asdasdsada_asdasd_sdsad0_vmname_3.vmdk"
scsi0:6.fileName = "vmname_3.vmdk"
To this:
scsi0:0.fileName = "vmname.vmdk"
scsi0:1.fileName = "vmname_1.vmdk"
scsi0:2.fileName = "vmname_2.vmdk"
scsi0:3.fileName = "vmname_3.vmdk"
scsi0:4.fileName = "vmname_4.vmdk"
scsi0:5.fileName = "vmname_5.vmdk"
scsi0:6.fileName = "vmname_6.vmdk"
I want to call NtOpensection but return 0xc0000024 error
UNICODE_STRING ObFileName;
OBJECT_ATTRIBUTES objA;
HANDLE hSectionHandle = NULL;
RtlInitUnicodeString(&ObFileName, L"\\??\\E:\\Myfile.dat");
InitializeObjectAttributes(&objA, &ObFileName, OBJ_CASE_INSENSITIVE, (HANDLE)NULL, (PSECURITY_DESCRIPTOR)NULL);
NTSTATUS ntStatus = _NtOpenSection(&hSectionHandle, SECTION_MAP_READ | SECTION_MAP_WRITE, &objA);
As for what the error means, you can check that here:
|===============================|=====================================================|
| 0xC0000024 | {Wrong Type} There is a mismatch between the type |
| STATUS_OBJECT_TYPE_MISMATCH | of object that is required by the requested |
| | operation and the type of object that |
| | is specified in the request. |
|===============================|=====================================================|
As for why it happens, that's for you to determine. Make sure "\\??\\E:\\Myfile.dat" is a valid name for a valid section object.
When I try something like this;
SetConsoleMode(hScreen, ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN);
it fails; the return value is zero and the mode isn't changed.
If, however, I do this:
SetConsoleMode(hScreen, ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
Then it works.
How do you set DISABLE_NEWLINE_AUTO_RETURN?