用于创建轮换的代码 Table 在 GDB 在线工作,但在 Code::Blocks 中不工作
Code for creating a Rotation Table working in GDB online, but not working in Code::Blocks
首先我想说我绝对不是 C 编程方面的专家,而且我已经有一段时间没有这样做了。
但我的任务是用 C 编写代码来解决有关组合数学的问题。
基本任务是,给定任何单词,构造一个正方形 table,其中包含一个单词所有可能的右移。第一步之后还有很多东西,但这是最重要的,也是给我带来麻烦的。
实际例子:
如果单词是“ababa”,“二维数组”应该包含:
- 阿巴巴
- aabab
- 咩咩
- 阿巴
- 粑粑
因为这个二维数组的大小总是长度 * 长度(所以如果单词的长度为 5,table 将是 5x5)我认为要做的事情是:
- 调用将长度作为参数传递的函数
- 使用 malloc 创建一个 char**,使其大小正确
- return 表示 char**
- 调用另一个函数用字符串填充它
我想出了以下代码,但实际上它在 GDB 在线版中完美运行,return在 Code::Blocks 中是一个错误。错误是:进程终止,状态为 -1073741819
令我困惑的是,当我尝试调试它时,Code::Blocks 中的代码确实有效。
这是分配数组的函数:
char** returnTable(int length){
char** rotationTable = malloc(length*sizeof(char));
char* values = calloc((length+1)*(length+1), sizeof(char));
for(int i=0; i<length; i++){
rotationTable[i] = values + i*(length+1);
rotationTable[i][0] = '[=12=]';
}
return rotationTable;}
这是用正确的词填充结构的函数:
void orderedConjugacyClass(char** table, char* word, int length){
//first word copied in the rotationTable
table[0] = strdup(word);
//let's start from the second row
int j = 1;
//p on the last char of the word
char* p = &table[j-1][length-1];
//q on the first
char* q = &table[j-1][0];
//buffer string, +1 for terminating character
char buffer[length+1];
buffer[0] = '[=13=]';
while(j < length){
strncat(buffer, p, 1);
strncat(buffer, q, length-1);
buffer[length] = '[=13=]';
table[j] = strdup(buffer);
p = &table[j][length-1];
q = &table[j][0];
//to cancel and reuse the buffer for next iteration
buffer[0]='[=13=]';
j++;
}
}
主要是我简单地调用了这两个函数。如果我只限于此,则代码(显然)没有问题。但是每当我尝试访问 table 的内容并用 printf 显示它时,就会出现问题并且 GDB 在线和 CodeBlocks 之间的输出“不同”:
int length = strlen(argv[1]);
char** rotationTable = returnTable(length);
orderedConjugacyClass(rotationTable, argv[1], length);
for(int j=0; j<length; j++)
printf("%s\n", rotationTable[j]);
for(int i=0; i<length; i++)
free(rotationTable[i]);
free(rotationTable);
return 0;
其他详细信息:我正在使用 Windows,MinGW 编译器。
感谢您的帮助和理解。
不要这样做:
SomeType something = malloc(length*sizeof(SomeType));
这样做:
SomeType something = malloc(length*sizeof(*something));
只有当 SomeType
的两种用法相同时,第一个才是正确的,并且很容易使它们不同,特别是如果您在程序中的某个点更改 SomeType
发展。
在这种情况下,您写了
char** rotationTable = malloc(length*sizeof(char));
这里的元素类型是char*
,但是你在sizeof
中使用了char
,导致你分配的太少了space。
如果你写了
char** rotationTable = malloc(length*sizeof(*rotationTable));
你不会有那个问题。
另请注意,您正在预先分配 rotationTable
的元素,然后将预先分配的数组替换为其他数组。最初分配的指针丢失了,所以你永远不会释放它们,所以你有内存泄漏。我不明白 returnTable
的意义。只需 orderedConjugacyClass
创建并 return 数组即可。
最后,这很愚蠢。
strncat(buffer, p, 1);
strncat(buffer, q, length-1);
buffer[length] = '[=14=]';
strncat
必须扫描目的地以找到其终点。但你知道尽头在哪里。所以花在扫描字符串上的周期是完全没有意义的。
buffer[0] = p[0];
memcpy(buffer+1, q, length-1);
buffer[length] = '[=15=]';
另一方面,p
和 q
也有点毫无意义,因为您可以直接从原始单词复制。实际上,您也可以摆脱 buffer
:
/* Production code should check if malloc succeeded */
char** conjTable(const char* word) {
size_t len = strlen(word);
char** table = malloc(len * sizeof(*table));
for (size_t i = 0; i < len; ++i) {
table[i] = malloc(len + 1);
memcpy(table[i], word + len - i, i);
memcpy(table[i] + i, word, len - i);
table[i][len] = '[=16=]';
}
return table;
}
首先我想说我绝对不是 C 编程方面的专家,而且我已经有一段时间没有这样做了。
但我的任务是用 C 编写代码来解决有关组合数学的问题。
基本任务是,给定任何单词,构造一个正方形 table,其中包含一个单词所有可能的右移。第一步之后还有很多东西,但这是最重要的,也是给我带来麻烦的。
实际例子: 如果单词是“ababa”,“二维数组”应该包含:
- 阿巴巴
- aabab
- 咩咩
- 阿巴
- 粑粑
因为这个二维数组的大小总是长度 * 长度(所以如果单词的长度为 5,table 将是 5x5)我认为要做的事情是:
- 调用将长度作为参数传递的函数
- 使用 malloc 创建一个 char**,使其大小正确
- return 表示 char**
- 调用另一个函数用字符串填充它
我想出了以下代码,但实际上它在 GDB 在线版中完美运行,return在 Code::Blocks 中是一个错误。错误是:进程终止,状态为 -1073741819
令我困惑的是,当我尝试调试它时,Code::Blocks 中的代码确实有效。 这是分配数组的函数:
char** returnTable(int length){
char** rotationTable = malloc(length*sizeof(char));
char* values = calloc((length+1)*(length+1), sizeof(char));
for(int i=0; i<length; i++){
rotationTable[i] = values + i*(length+1);
rotationTable[i][0] = '[=12=]';
}
return rotationTable;}
这是用正确的词填充结构的函数:
void orderedConjugacyClass(char** table, char* word, int length){
//first word copied in the rotationTable
table[0] = strdup(word);
//let's start from the second row
int j = 1;
//p on the last char of the word
char* p = &table[j-1][length-1];
//q on the first
char* q = &table[j-1][0];
//buffer string, +1 for terminating character
char buffer[length+1];
buffer[0] = '[=13=]';
while(j < length){
strncat(buffer, p, 1);
strncat(buffer, q, length-1);
buffer[length] = '[=13=]';
table[j] = strdup(buffer);
p = &table[j][length-1];
q = &table[j][0];
//to cancel and reuse the buffer for next iteration
buffer[0]='[=13=]';
j++;
}
}
主要是我简单地调用了这两个函数。如果我只限于此,则代码(显然)没有问题。但是每当我尝试访问 table 的内容并用 printf 显示它时,就会出现问题并且 GDB 在线和 CodeBlocks 之间的输出“不同”:
int length = strlen(argv[1]);
char** rotationTable = returnTable(length);
orderedConjugacyClass(rotationTable, argv[1], length);
for(int j=0; j<length; j++)
printf("%s\n", rotationTable[j]);
for(int i=0; i<length; i++)
free(rotationTable[i]);
free(rotationTable);
return 0;
其他详细信息:我正在使用 Windows,MinGW 编译器。
感谢您的帮助和理解。
不要这样做:
SomeType something = malloc(length*sizeof(SomeType));
这样做:
SomeType something = malloc(length*sizeof(*something));
只有当 SomeType
的两种用法相同时,第一个才是正确的,并且很容易使它们不同,特别是如果您在程序中的某个点更改 SomeType
发展。
在这种情况下,您写了
char** rotationTable = malloc(length*sizeof(char));
这里的元素类型是char*
,但是你在sizeof
中使用了char
,导致你分配的太少了space。
如果你写了
char** rotationTable = malloc(length*sizeof(*rotationTable));
你不会有那个问题。
另请注意,您正在预先分配 rotationTable
的元素,然后将预先分配的数组替换为其他数组。最初分配的指针丢失了,所以你永远不会释放它们,所以你有内存泄漏。我不明白 returnTable
的意义。只需 orderedConjugacyClass
创建并 return 数组即可。
最后,这很愚蠢。
strncat(buffer, p, 1);
strncat(buffer, q, length-1);
buffer[length] = '[=14=]';
strncat
必须扫描目的地以找到其终点。但你知道尽头在哪里。所以花在扫描字符串上的周期是完全没有意义的。
buffer[0] = p[0];
memcpy(buffer+1, q, length-1);
buffer[length] = '[=15=]';
另一方面,p
和 q
也有点毫无意义,因为您可以直接从原始单词复制。实际上,您也可以摆脱 buffer
:
/* Production code should check if malloc succeeded */
char** conjTable(const char* word) {
size_t len = strlen(word);
char** table = malloc(len * sizeof(*table));
for (size_t i = 0; i < len; ++i) {
table[i] = malloc(len + 1);
memcpy(table[i], word + len - i, i);
memcpy(table[i] + i, word, len - i);
table[i][len] = '[=16=]';
}
return table;
}