Can strcmp() Compare a Dynamic Character Array with a Static Character array? - c++

Perhaps this is a stupid question, but the reason I ask is because I'm using strcmp() to compare a dynamic array with a static array and it's seemingly giving the wrong result. The arrays should be equal, but strcmp() is returning false. When I pause my program, the only two things that differ between those arrays are their memory locations.
I can't show you the whole code, but here's part of my function which has these two variables in it:
stock * Table::retrieveStock(const char tick[])
{
uint8_t index = hashing(tick);
if (table[index])
{
bool test = strcmp(table[index]->data->getTick(), tick);
//irrelevant code
and here's how some of the pointers are declared in the Table class:
struct node
{
stock * data;
node * next;
node()
{
stock();
next = nullptr;
}
node(stock *& item)
{
data = item;
next = nullptr;
}
};
node ** table;
I have an array of class objects in it, anyways, the point is that I'm comparing two tick values, which should be equal. One I'm pulling out of the object with the getTick() function:
const char * stock::getTick() const
{
return tick;
}
and one is passed into the function: const char tick[]. I'm quite clueless as to what is wrong with my code here. I would love to give you guys more code to work with, but I can't see how it would do anything but make solving this issue more difficult for you.
Edit: Maybe this will help; I just thought of it. This is exactly what my compiler says the values are:
curr->data 0x005d93e8 {tick=0x005d9f38 "TSLA" name=0x005da100 "2" value=2.00000000 ...} stock *
and
tick 0x004afb20 "TSLA" const char *

strcmp() returns 0 for a match (and non-zero for no match). It doesn't return true or false as you are expecting.

Related

Attempting to Display a 3x3 table with double digit numbers using char array

I am writing this program for class and I cannot seem to figure out how to make my Char array print values bigger than 1-9 as otherwise players will have to do math to be able to calculate which slot they want. Which I feel ruins the fun of the game. However, I am newer to C++ and I cannot seem to get it to work. Any help is appreciated, this is the Array, and this is the program.
class TTTBoard {
public:
void PrintBoard();
char board[9] = { '1','2','3','4','5','6','7','8','9' };
char board2[9] = { "10","11","12","13","14","15","16","17","18"};
char board3[9] = { "19","20","21","22","23","24","25","26","27" };
int WinXY();
int WhosMove();
void Update();
int gameWin();
void AI();
void UserSelectASlot();
bool gameend();
};
My functions I have declared on in my source file, however whenever I try char * board2[9].......etc It gives me an error for many functions saying I cannot assign an int value to *char?
This is one piece of code among many others from the UserSelectASlot(); Function.
else if (Spot == 10 && game.board2[0] != 'O' && game.board2[0] != 'X')
{
game.board2[0] = 'X';
}
I also tried doing char string board[9][19] however that does not work either due to errors, over 100 so it stopped counting.
My current errors for the first code above are "Too many Initializers"
Any help is greatly appreciated!
Thanks!
The 2nd and 3rd char arrays are actually arrays of strings (“)
so change the declaration to:
const char* array[9]
About the error you received , my guess is that you passed array[i] to a function that expects a char so replace it with array[i][0], array[i][1] those are the 2 characters in the string.
BTW,
You don’t need to work with characters but with numbers , integers and in the print function you can just map the int values to the right character.

Unsigned long back into pointer to a class

Now, I am doing a exercise in introduction to algorithms by using C++.
The question is :
Explain how to implement doubly linked lists using only one pointer
value x.np per item instead of the usual two (next and prev). Assume
that all pointer values can be interpreted as k-bit integers, and
define x.np = x.next XOR x.prev, the k-bit "exclusive-or" of x.next
and x.prev. (The value NIL is represented by 0). Be sure to describe
what information you need to access the head of the list. Show how to
implement the SEARCH, INSERT and DELETE operations on such a list.
Also show how to reverse such a list in O(1) time.
In the XOR function, I first convert pointer to class into unsigned long and Xor these two value. And then convert the result back to a pointer to class. I don't know why it doesn't work. Here is my code:
struct node
{
int key;
node *np;
} ;
struct list_n
{
node *head;
node *tail;
};
The above are two structs and below is insertion
void insert_element(list_n *_list, int _key)
{
node *present_node= new node;
present_node->key=_key;
present_node->np=xor_gate(nullptr,_list->tail);
if(_list->tail) _list-> tail->np=xor_gate(present_node,xor_gate(nullptr,_list->tail->np ));
if(!_list->head) _list->head=present_node;
_list->tail=present_node;
}
Below is the Xor gate :
node *xor_gate(node *left,node *right)
{
unsigned long result;
result = ( reinterpret_cast<unsigned long>(left) ) ^ ( reinterpret_cast<unsigned long>(right) );
node *output =new node;
output = reinterpret_cast<node*> (result); // yes or no
return output ;
}
void list_n_inti(list_n *a )
{
a->head =nullptr;
a->tail =nullptr;
}
I have review the code several times. I think the problem is caused by XOR gate.
If you have found the bug please tell me. And if you have any other ways to answer this question. please tell me.
Thank you
There is a memory leak in xor_gate, but I think the code works if you compile it as 32-bits. If you compile it as 64-bits, then unsigned long cannot contain a pointer generally.
try this:
#include <cstdint> // for uintptr_t
node *xor_gate(node *left,node *right)
{
using std::uintptr_t;
uintptr_t result = ( reinterpret_cast<uintptr_t>(left) ) ^ ( reinterpret_cast<uintptr_t>(right) );
return reinterpret_cast<node*> (result);
}

C - passing an array by reference - only first element set

I have a function which should modify an array (of floats) in the original parent function. I am using the following code:
void sortFunction(Word**words, int wordCount){ //to sure if two * are correct (pointer to an array..?)
int i = 0;
for(i=0;i<wordCount-1;i++){
Word first = *words[i]; //values fine
Word second = *words[i+1]; //weird values, causes segfault
if(first.data[0] > second.data[0]){
//do stuff
}
}
}
int main(int argc, char ** argv){
Word* words = NULL;
int wordsCount = ...
//filling the array in a loop and using realloc for memory allocation
//Here, the array is filled correctly (verified)
sortFunction(&words, wordsCount);
}
Where Word is a typedef struct and Word.data is the (dynamic) float array. When checking in the parent function, the array is allocated and the values set correctly.
I have tried with about 10 elements in the array, but always only the first ([0]) element is fine in the sortFunction(), second and all others are messed up. I also have an int propery in the struct, and when I try to print it for the second element, I get something over 1 billion.
I assume I am not passing the array correctly - I use the following code (just a sample) to pass regular variables, so I tried to modify it for an array, but apparently, not correctly. What is the right way to do this for an array?
void foo(int*var){
*var=8;
}
int main(){
int var = 5;
changeVar(&var);
}
Thanks in advance for any tips!
Postfix [] has higher precedence than unary *, so *words[i] is parsed as *(words[i]), which isn't what you want.
You need to dereference the words pointer before applying the subscript, so you need to explicitly group the * operator with words using parentheses:
Word first = (*words)[i];
Word second = (*words)[i + 1];
First, you do not need to pass **, just one is enough, because you will be passing the address of your array anyway:
void sortFunction(Word* words, int wordCount)
and call it as:
sortFunction(words, wordsCount);
Second, the Undefined behavior originates in the following statement:
Word first = *words[i]; Word second = *words[i+1];
It should have been (*words)[i] but still, you are copying structs, so your dynamic data array is not copied correctly. avoid this useless copy, and use this instead, AFTER changing the protoype of sortFunction:
Word* first = &words[i];
Word* second = &words[i+1];
if(first->data[0] > second->data[0])
p.s: This does not guarantee that the rest of your code is correct, just comments of the parts you showed of the code.

Example why someone should use triple-pointers in C/C++?

I'm searching for an example or explanation why someone should (or should not) use triple-pointers in C/C++.
Are there any examples where triple-pointer arise?
I am especially looking for source-code which uses triple-pointers.
The best example that comes to mind is a sparse multi-level table. For instance one way to implement properties for Unicode characters might be:
prop_type ***proptable;
...
prop_type prop = proptable[c>>14][c>>7&0x7f][c&0x7f];
In this case proptable would need to have a triple-pointer type (and possibly quadruple pointer if the final resulting type is a pointer type). The reason for doing this as multiple levels rather than one flat table is that, at the first and second levels, multiple entries can point to the same subtable when the contents are all the same (e.g. huge CJK ranges).
Here's another example of a multi-level table that I implemented; I can't say I'm terribly proud of the design but given the constraints the code has to satisfy, it's one of the least-bad implementation choices:
http://git.musl-libc.org/cgit/musl/tree/src/aio/aio.c?id=56fbaa3bbe73f12af2bfbbcf2adb196e6f9fe264
If you need to return an array of pointers to variable length strings via a function parameter:
int array_of_strings(int *num_strings, char ***string_data)
{
int n = 32;
char **pointers = malloc(n * sizeof(*pointers));
if (pointers == 0)
return -1; // Failure
char line[256];
int i;
for (i = 0; i < n && fgets(line, sizeof(line), stdin) != 0; i++)
{
size_t len = strlen(line);
if (line[len-1] == '\n')
line[len-1] = '\0';
pointers[i] = strdup(line);
if (pointers[i] == 0)
{
// Release already allocated resources
for (int j = 0; j < i; j++)
free(pointers[j]);
free(pointers);
return -1; // Failure
}
}
*num_strings = i;
*string_data = pointers;
return 0; // Success
}
Compiled code.
If you use a linked list you have to store the address of the first element of the list ( first pointer ) .
If you need to change in that list you need another pointer ( two pointer)
If you need to pass your list that you are changing in two pointers and change it in another function you need another pointer ( three pointer )...
They are a lots of examples
I've used triple pointers in C++:
There is an interface written for a Java program:
https://github.com/BenLand100/SMART/blob/master/src/SMARTPlugin.h
and it takes an array of strings.
typedef void (*_SMARTPluginInit)(SMARTInfo *ptr, bool *replace, int *buttonc, char ***buttonv, int **buttonid, _SMARTButtonPressed *buttonproc);
Then in my program I do:
char* btnTexts[2] = {"Disable OpenGL_Enable OpenGL", "Enable Debug_Disable glDebug"}; //array of C-style strings.
void SMARTPluginInit(SMARTInfo* ptr, bool* ReplaceButtons, int* ButtonCount, char*** ButtonTexts, int** ButtonIDs, _SMARTButtonPressed* ButtonCallback)
{
*ButtonText = btnTexts; //return an array of strings.
}
but in C++, you can use a reference instead of pointer and it'd become:
void SMARTPluginInit(SMARTInfo* ptr, bool* ReplaceButtons, int* ButtonCount, char** &ButtonTexts, int** ButtonIDs, _SMARTButtonPressed* ButtonCallback)
{
ButtonText = btnTexts; //return an array of strings.
}
Notice now that "ButtonTexts" is a reference to an array of C-style strings now.
A char*** can be a pointer to an array of C-style strings and that's one time that you'd use it.
A very simple example is a pointer to an array of arrays of arrays.
Triple pointer is a pointer variable that points to a pointer which in turn points to another pointer. The use of this complex programming technique is that usually in which companies process tons and tons of data at one time .A single pointer would point to a single block of data (suppose in a large file) using the triple pointer would result in 3 times faster processing as different blocks of data(in the same file) can be pointed by different pointer and thus data could be accessed/processed faster (unlike 1 pointer going through the whole file).

Testing constructor initialization list

I am working on a test which checks if all class attributes are initialized in a constructor.
My current solution works for non pointer attributes:
void CSplitVectorTest::TestConstructorInitialization()
{
const size_t memorySize = sizeof(CSplitVector);
char* pBuffer1 = (char*) malloc(memorySize);
char* pBuffer2 = (char*) malloc(memorySize);
memset(pBuffer1,'?',memorySize);
memset(pBuffer2,'-',memorySize);
new(pBuffer1) CSplitVector;
new(pBuffer2) CSplitVector;
const bool bObjectsAreEqual = memcmp(pBuffer1,pBuffer2,memorySize)==0;
if (!TEST(bObjectsAreEqual))
{
COMMENT("Constructor initialization list not complete!");
}
free(pBuffer1);
free(pBuffer2);
}
Do you have an idea how could it be improved to test if pointers are initialized?
Your test checks whether every byte of the object has been written over by the constructor. As a straight memory check it looks OK, although if the class contains other objects which don't necessarily initialise themselves fully, you may be in trouble.
That said, my main question would be: Is it really an effective test? For example, is it critical that every attribute in the CSplitVector class is initialised by the initialisation list? Do you perhaps have some which may not need to be initialised at this point? Also, how about checking whether the attributes are set to values that you'd expect?
Instead of comparing byte by byte, you probably should use the right padding or word size, and test if any byte of each word got initialized. That way you will probably get around compiler using padding and constructor leaving uninitialized bytes between padded shorter-than-word fields.
To test the real padding size, shooting from the hip, following code should do it pretty reliably:
struct PaddingTest {
volatile char c; // volatile probably not needed, but will not hurt either
volatile int i;
static int getCharPadding() {
PaddingTest *t = new PaddingTest;
int diff = (int)(&(t->i)) - (int)&((t->c));
delete t;
return diff;
}
}
Edit: You still need the two objects, but you no longer compare them to each others, you just compare each initialized data to the memset value, and if either object has any change, it means the word got touched (also on the other one, it's just chance that it got initialized to same value you memset).
I found a solution for mentioned problems, tested it with initialized/not initialized pointers and with different length types.
In test header I added #pragma pack(1) (I am working on gcc)
#pragma pack(1)
#include <CSplitVector>
Test got a little bit complicated:
void CSplitVectorTest::TestConstructorInitialization()
{
const size_t memorySize = sizeof(CSplitVector);
char* pBuffer = (char*) malloc(memorySize);
memset(pBuffer,'?',memorySize);
CSplitVector* pSplitVector = new(pBuffer) CSplitVector;
// find pointers for all '?'
QList<char*> aFound;
char* pFoundChar = (char*) memchr(pBuffer,'?',memorySize);
while (pFoundChar)
{
aFound.append(pFoundChar);
char* pStartFrom = pFoundChar+1;
pFoundChar = (char*) memchr(pStartFrom,'?',memorySize-(int)(pStartFrom-pBuffer));
}
// if there are any '?'....
if (aFound.count())
{
// allocate the same area with '-'...
pSplitVector->~CSplitVector();
memset(pBuffer,'-',memorySize);
pSplitVector = new(pBuffer) CSplitVector;
// and check if places found before contain '-'
while (aFound.count())
{
pFoundChar = aFound.takeFirst();
if (*pFoundChar=='-')
{
// if yes then class has uninitialized attribute
TEST_FAILED("Constructor initialization list not complete!");
pSplitVector->~CSplitVector();
free(pBuffer);
return;
}
}
}
// if no then all attributes are initialized
pSplitVector->~CSplitVector();
free(pBuffer);
TEST(true);
}
Feel free to point any flaws in this solution.