How to use some part of array in Glimpse Structure c language - c

Basically, my question is how can I use some part of an array? For example, first byte equal to structure.code then other four byte equal structure.timestamps etc. I'm new, thanks for understands.
My function:
void GlimpseStructures(char buffer[])
{
int i = 0;
HeartbeatPackage a;
a.to_little_endian();
a.code = buffer[0];
for (i = 1; i < 5; i++)
{
a.timestamp += buffer[i];
}
for (i = 5; i < 9; i++)
{
buffer[i] += a.nanosecond_elapsed;
printf("nanosecond:%d/n", a.nanosecond_elapsed);
}
}

Related

What causes the difference between memcpy and strcpy in copying openssl BIGNUM

This problem bothered me for an hour when I was programming, but I still didn't know the error of the original method after solving it.
void generate_r_vector(char (*r_vector)[17],char *random_r) {
BIGNUM* vector[127];
char r_v[128][17];
char flag[17];
memset(flag, 0, sizeof(flag));
int bits = 128;
int top = 0;
int bottom = 0;
for (int i = 0; i < 127; i++) {
vector[i] = BN_new();
BN_rand(vector[i], bits, top, bottom);
memset(r_v[i], 0, sizeof(r_v[i]));
BN_bn2bin(vector[i], r_v[i]);
}
memset(r_v[127], 0, sizeof(r_v[127]));
for (int i = 0; i < 127; i++) {
for (int j = 0; j < 16; j++) {
flag[j] = flag[j] ^ r_v[i][j];
}
}
for (int i = 0; i < 16; i++) {
r_v[127][i] = flag[i] ^ random_r[i];
}
for (int i = 0; i < 128; i++) {
memcpy(r_vector[i], r_v[i], 17);
}
}
Using memcpy to copy these arrays, when XOR in the main function, you can get the original string random_r.
But using the strcpy function to copy these arrays in the main function XOR, can not get the original random_r.
What I learned about OpenSSL:here, a 128 bit large number is converted into binary, and then every 4 bits are converted into a decimal, which is stored in the char array.
Memcpy copies by byte, while strcpy can only copy strings.
I can't understand why the XOR results of the two copy methods are different when they are both stored in char arrays.
My English level is not good, I hope you programmers can understand my expression. I sincerely hope you can answer my question. thank you
=======================2021/2/21 updata=====================================
I provide a program that can run directly, hoping to alleviate the problems caused by my unclear expression.
int main() {
char* random_r="1234567891234567";//长度16 算上'\0'17
char r_vector[128][17];
BIGNUM* vector[127];
char r_v[128][17];
char flag[17];//判断是否一致
memset(flag, 0, sizeof(flag));
int bits = 128;
int top = 0;
int bottom = 0;
for (int i = 0; i < 127; i++) {
vector[i] = BN_new();
BN_rand(vector[i], bits, top, bottom);
memset(r_v[i], 0, sizeof(r_v[i]));
BN_bn2bin(vector[i], r_v[i]);
}
memset(r_v[127], 0, sizeof(r_v[127]));
for (int i = 0; i < 127; i++) {
for (int j = 0; j < 16; j++) {
flag[j] = flag[j] ^ r_v[i][j];
}
}
for (int i = 0; i < 16; i++) {
r_v[127][i] = flag[i] ^ random_r[i];
}
//至此生成了128个向量,这些向量的异或之和正好是random_r的值,ans可以验证这个结论
char ans[17];
memset(ans, 0, sizeof(ans));
for (int i = 0; i < 128; i++) {
for (int j = 0; j < 16; j++) {
ans[j] = ans[j] ^ r_v[i][j];
}
}
printf("the target XOR result is:%s\n", ans);//
//下面使用memcpy的形式拷贝并求异或值
for (int i = 0; i < 128; i++) {
memcpy(r_vector[i], r_v[i], 17);//逐字节拷贝解决问题strcpy会出现问题,原因未知
}
memset(ans, 0, sizeof(ans));
for (int i = 0; i < 128; i++) {
for (int j = 0; j < 16; j++) {
ans[j] = ans[j] ^ r_vector[i][j];
}
}
printf("using memcpy copying and the result is:%s\n", ans);//这是正确的结果
memset(r_vector, 0, sizeof(r_vector));
for (int i = 0; i < 128; i++) {
strcpy(r_vector[i], r_v[i]);//strcpy会出现问题,原因未知
}
memset(ans, 0, sizeof(ans));
for (int i = 0; i < 128; i++) {
for (int j = 0; j < 16; j++) {
ans[j] = ans[j] ^ r_vector[i][j];
}
}
printf("using strcpy copying and the result is:%s\n", ans);
int err_count = 0;
for (int i = 0; i < 128; i++) {
if (strcmp(r_vector[i], r_v[i]) != 0) err_count++;
}
printf("after using strcpy() each vector using strcmp() with orignal r_v,the different vector nums:%d\n", err_count);
system("pause");
return 0;
}
Running results in vs2019
the target XOR result is:1234567891234567
using memcpy copying and the result is:1234567891234567
using strcpy copying and the result is:12eH⊙碡?H-c纫
after using strcpy() each vector using strcmp() with orignal r_v,the different vector nums:0
What causes the difference between memcpy and strcpy in copying openssl BIGNUM
The comment "BIGNUM values are not C strings, so strcpy() won't work." may be not enough to enlighten you.
BIGNUM values can contain a byte with all bits set to 0, called the null character, and since that is used to terminate a character string, strcpy() stops there and doesn't copy the rest of the BIGNUM value.
Even when strcpy and memcpy are both used for char arrays, they don't do exactly the same thing. memcpy copies a fixed number of bytes, which you give as the third argument. strcpy doesn't just copy from one char array or pointer to another, it figures out how much to copy in a completely different way, namely by checking for a 0 value in the chars to copy.
Even though r_vector points to char arrays, they don't have to be strings: If they are not 0-terminated or have 0 values at other positions things will behave differently than for a string.

Swapping row of 2D string array in C

The module that swaps row to make an array sorted in ascii ascending order keeps returning error.
const int MAX = 10;
const int MAX_STR = 80;
void asciiOrder(char (*buffer)[MAX_STR]);
void asciiOrder(char (*buffer)[MAX_STR]) {
char * temp;
for (int i = 0; i < sizeof(buffer) / sizeof (buffer[0]) - 1; i++) {
for (int j = 1; i + j < sizeof(buffer) / sizeof(buffer[0]); j++) {
for (int k = 0; k < strlen(buffer[i]) && buffer[i][k] != NULL; k++) {
if (buffer[i][k] > buffer[i+j][k]) {
temp = buffer[i+j];
buffer[i+j] = buffer[i];
buffer[i] = temp;
break;
}
}
}
}
}
And this is the error I got from the entire code:
practice102.c:87:23: error: assignment to expression with array type
buffer[i+j] = buffer[i];
^
practice102.c:88:21: error: assignment to expression with array type
buffer[i] = temp;
I searched other posts but still don't know why.
How to solve this problem?
C forbidden to assign a 2D array without specify the two index.
You have to write something like
buffer[a][b] = buffer[c][d]
whatever your a,b,c,d are.
Also be sure that your buffer temp are filled and/or allocated.

How to make strings stick together while radix sorting?

I have to make a program that sort strings (with exact length 7 chars) by using radix sort. I already made a function that sort each column separately. My problem is how to make the whole string move, not just one char. It's really problematic for me to see how should it work in C.
I made one array "char strings[3][8]" and "char output[3][8]" to get sorted 3 strings with exact 7 chars in each one. For example sorting these strings:
strcpy(strings[0], "kupbars");
strcpy(strings[1], "daparba");
strcpy(strings[2], "jykaxaw");
In output I get:
dakaaaa
juparbs
kypbxrw
Each column is sorted correctly but chars don't stick together. I tried many ways for 3 hours but nothing works.
My code looks like this:
void countingSort(char a[][8], char b[][8]) {
int c[123];
for (int pos = 6; pos >= 0; pos--) {
for (int i = 0; i < 123; i++)
c[i] = 0;
for (int i = 0; i < 3; i++)
c[(int)a[i][pos]]++;
for (int i = 1; i < 123; i++)
c[i] += c[i - 1];
for (int i = 2; i >= 0; i--) {
b[--c[(int)a[i][pos]]][pos] = a[i][pos];
}
}
}
(There are constants limiting string length etc. because it's easy to change it to variable - I just focused on getting this program work properly.)
Try changing the loop to move an entire string:
for (int i = 2; i >= 0; i--) {
int k = --c[(int)a[i][pos]];
for(int j = 0; j < 8; j++) {
b[k][j] = a[i][j];
}
}
You could do a circular list but it's a little overhead. I propose you to use memmove().
#include <string.h>
void array_move_forward(char array[3][8]) {
for (int i = 0; i < 3; i++) {
char tmp = array[i][6];
memmove(array[i] + 1, array[i], 6);
array[i][0] = tmp;
}
}
void array_move_rewind(char array[3][8]) {
for (int i = 0; i < 3; i++) {
char tmp = array[i][0];
memmove(array[i], array[i] + 1, 6);
array[i][6] = tmp;
}
}
A other solution would be to manipulate your string yourself and using a index, that indicate the first letter of your string.
{
char str[7];
int i = 0;
...
int j = i;
for (int k = 0; k < 7; k++) {
char tmp = str[j++ % 7];
}
}
With that you could rotate your string just with i++ or i--.
struct my_string_radix {
char str[7];
int begin;
}

How to "combine" two int arrays?

Hello i have a little problem trying to "mix" two string arrays, i have searched about it but i have only found how to merge them or concatenate them, but thats not what i need.
i have two int arrays like this:
int no_items = 5;
int parent1[no_items], parent2[no_items];
if the arrays contains for example:
parent1[0] = 1;
parent1[1] = 2;
parent1[2] = 3;
parent1[3] = 4;
parent1[4] = 5;
and:
parent2[0] = 5;
parent2[1] = 1;
parent2[2] = 2;
parent2[3] = 3;
parent2[4] = 4;
given a "cross" point, for example 2:
parent1 should have his 2 first elements and the rest of parent2, and parent2 should have his first 2 elements and the rest of parent1. So the result should be:
parent1: 1,2 | 5,3,4
parent2: 5,1 | 2,3,4
where "|" is the break point index and the rest of elements should not be repeated.
How can i get this kind of mixing two int arrays? Thanks you!
at the moment i have this:
for(i = 0; i < cross_point; i++)
{
sprintf(buffer, "%d,", parent1[i]);
strcat(line1, buffer);
}
for(i = 0; i < cross_point; i++)
{
sprintf(buffer, "%d,", parent2[i]);
strcat(line2, buffer);
}
but i don´t know how to go further than the cross point.
int *find(int *begin, int *end, int value)
{
int *p = begin;
for ( ; p != end; ++p)
if (*p == value) break;
return p;
}
int i, j;
int output1[no_items] = {0};
int output2[no_items] = {0};
int crosspoint = 3;
memcpy(output1, parent1, crosspoint * sizeof(int));
for (i = crosspoint, j = 0; i < no_items; ++i)
{
while (find(output1, output1+i, parent2[j]) != output1+i) ++j;
output1[i] = parent2[j];
}
memcpy(output2, parent2, crosspoint * sizeof(int));
for (i = crosspoint, j = 0; i < no_items; ++i)
{
while (find(output2, output2+i, parent1[j]) != output2+i) ++j;
output2[i] = parent1[j];
}
memcpy(parent1, output1, sizeof(parent1));
memcpy(parent2, output2, sizeof(parent2));
Demo: http://ideone.com/xUt6nQ
something like this should do it if you aren't concerned about creating temporaries:
int no_items = 5;
int output1[no_items];
int output2[no_items];
for (int i = 0; i < no_items; i++){
if(i < crosspoint){
output1[i] = parent1[i];
output2[i] = parent2[i];
}else{
output1[i] = parent2[i];
output2[i] = parent1[i];
}
}
If you are concerned about temporaries you need to swap the values, the logic should be fairly similar to above.
int no_items = 5;
int temp = 0;
for (int i = 0; i < no_items; i++){
if(i < crosspoint){
/* don't need to do anything here */
}else{
temp = parent1[i];
parent1[i] = parent2[i];
parent2[i] = temp;
}
}

Expression cannot be evaluated. Malloc fail

I' having a problem allocating a structure in a function. Here is the code(I'm currently using visual studio 2008):
Mat3x3* ProdMat(Mat3x3 *m, Mat3x3 *n)
{
if(m == NULL || n == NULL)
{
cout << "\t[W] Cannot compute product of the two matrixes one or both are NULL." << endl;
return NULL;
}
Mat3x3 *p; // product
int i, j;
float sum = 0;
p = (Mat3x3*)malloc(sizeof(Mat3x3)); // <= Exp cannot be evaluated
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
{
sum = 0;
for(int k = 0; k < 3; k++)
{
float a = m->a[i][k];
float b = n->a[k][j];
sum += a * b;
}
p->a[i][j] = sum;
}
}
return p;
}
P contains a matrix with 9 entries. Here is the context in which the error is given:
Mat3x3* compute_final_trans(Trans **transes) // compute product of all transformation matrixes from right to left
{
int k_trans = 0, i, j;
Mat3x3 *final_trans;
if(transes == NULL)
{
printf("\t[E] Cannot compute sequence of NULL transformations.\n");
return NULL;
}
final_trans = (Mat3x3*)malloc(sizeof(final_trans));
for(i = 0; i < 3; i++) // generate eye matrix
for(j = 0; j < 3; j++)
{
if(i == j)
{
final_trans->a[i][j] = 1;
}
else
{
final_trans->a[i][j] = 0;
}
}
while(transes[k_trans++]);
for(i = k_trans - 2; i >= 0; i--)
{
final_trans = ProdMat(transes[i]->matrix, final_trans); // <= ERROR
}
return final_trans;
}
Final trans is initialised as the eye matrix and transes have been succesfully computed before this step(before calling compute_final_trans). The while is used to retreieve the number of transformations that transes contains. At line:
final_trans = ProdMat(transes[i]->matrix, final_trans);
ProdMat fails to allocate memory for p which is a pointer to a Mat3x3 structure.
perror suggests that there isn't enough memory to allocate to the structure. However I'm only using 1GB of RAM(4GB in all).
Any help/suggestion/reference will be very much appreciated.
Sebi
malloc(sizeof(final_trans))
This is bad. You are only allocating enough space for a pointer, not space for an array.

Resources