c - 凯撒密码 - 有条件的跳跃或移动取决于未初始化的值
问题描述
我的学校项目有问题。项目是关于凯撒密码的,程序输入包括消息长度、加密消息、截获不良消息(几个字符是正确的)。程序的输出是一个解密的消息。程序正确解密,但是 Valgrind 的输出有错误。此外,我认为我对输入数据条件的处理不当。
有我的程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* One character rotation */
char rotate(char original, int offset){
char * alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
if (original >= 'A' && original <= 'Z') {
return alpha[(original - 'A' + offset) % 52];
}
else{
return alpha[(original - 'a' + 26 + offset) % 52];
}
}
/* String decoding */
void shift(const char *src, char *dst, int offset){
for (int i = 0; i < strlen(src); i++) {
dst[i] = rotate(src[i], offset);
}
}
void printResult(char * coded, char * tapped, int size) {
char decoded[size];
int matchingLetters = 0, max = 0, recording = 0;
for (int i = 0; i <= 52; i++) {
shift(coded, decoded, i);
// Zjisteni poctu matchingLetters pismen
for (int j = 0; j < size; j++ ) {
if(tapped[j] == decoded[j])
matchingLetters++;
}
if(matchingLetters >= max){
recording = i;
max = matchingLetters;
}
matchingLetters = 0;
}
shift(coded, decoded, recording);
printf("%s\n",decoded);
}
/* The main program */
int main(int argc, char *argv[])
{
int size;
if (scanf("%d\n", &size) != 1) {
printf("Error: bad input!\n");
return 100;
}
char coded[size + 1];
char tapped[size + 1];
if (scanf("%[a-zA-Z]\n", coded) != 1 || scanf("%[a-zA-Z]\n", tapped) != 1) {
printf("Error: bad input!\n");
return 100;
}
if (strlen(coded) != size || strlen(tapped) != size) {
fprintf(stderr, "Error: bad input length!");
return 101;
}
printResult(coded, tapped, size);
return 0;
}
Valgrind 输出:
==866== Memcheck, a memory error detector
==866== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==866== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==866== Command: src/main
==866==
==866== Conditional jump or move depends on uninitialised value(s)
==866== at 0x4C2EDB8: strlen (vg_replace_strmem.c:454)
==866== by 0x4EA0FA1: puts (ioputs.c:35)
==866== by 0x400B1D: printResult (main.c:50)
==866== by 0x400BE7: main (main.c:76)
==866==
==866==
==866== HEAP SUMMARY:
==866== in use at exit: 0 bytes in 0 blocks
==866== total heap usage: 2 allocs, 2 frees, 8,192 bytes allocated
==866==
==866== All heap blocks were freed -- no leaks are possible
==866==
==866== For counts of detected and suppressed errors, rerun with: -v
==866== Use --track-origins=yes to see where uninitialised values come from
==866== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
谢谢你的任何建议。
解决方案
- Shift 不会终止dst(已解码),这可能会导致strlen进入其他内存。
- Decoded不够大,无法包含字符串终止符。
作为风格说明:
for (int i = 0; i < strlen(src); i++)
对许多 C 程序员来说就像是黑板上的钉子。编译器是否可以清理它并不重要。
推荐阅读
- java - java.lang.AbstractMethodError:org.apache.cxf.transport.http.asyncclient.AsyncHTTPConduitFactory.createConduit
- javascript - TypeError:无法读取 null 的属性“memberCount”
- python - 如何使函数检查字符串中有多少个辅音或元音?
- oracle - 如何增加 Oracle Reports 6i 中显示的行数?
- typescript - 防止 TypeScript 编译器退出批处理脚本
- linux - 如何在linux终端命令中使用#
- android - 使用 Jetpack 导航组件在一个屏幕上显示多个片段
- ios - 从 Native iOS 向 React Native 发送自定义数据类型
- excel - 按名称访问工作表,包括 ThisWorkbook
- javascript - 每次单击跨度时如何为 div 运行函数?