我创建了一个模拟标记/扫描垃圾收集算法的小程序。在大多数情况下,它完全有一个例外:我的自定义is_int()
函数,用于区分mem_block->mem_block
的引用和pointer_variable->mem_block
的引用(因为pointer_variable
名称可以& #39; t是一个整数)当True
在运行整个程序时传递给它
0
当我在Python交互模式下运行该函数时,正确运行is_int(0)
会返回True
。但是在运行整个程序时,if is_int(x)/else
会在x == 0
时将我转储到else分支中,但我无法找出原因。
以下是源代码和一些演示情况的屏幕截图,最相关的代码块用"#问题代码"表示:
import argparse
import re
import sys
class MemoryObject():
def __init__(self):
self.marked = 0
self.references = [] # list of <MemoryObject> references
def arg_parse():
# Sets up a parser object for handling arguments passed to the program
parser = argparse.ArgumentParser(description='Some description')
parser.add_argument('filename', help='Filename parameter for input file')
return parser.parse_args()
# PROBLEM CODE
def is_int(s):
# Determines if the given variable contains only an integer value
# Primarily used to distinguish memory-blocks from named
# pointer variables
if int(s):
return True
elif s == 0:
return True
else:
return False
# /PROBLEM CODE
def node_trace(current_node, node_dict):
# This function recursively simulates the "mark" phase of
# Mark/Sweep G.C. using a dictionary of <MemoryObject>
# each element therin containing its list of references
#
# Each node traversed is marked, and the function returns
# if the node has already been checked
#
# This function assumed the inital call was passed the RootMemoryBlock
# as it's starting point, which garuntees only accessible memory will
# be marked since RootMemoryBlock only references pointers which
# in turn, by definition, only reference chains of accessible memory
if current_node.marked == 1:
return
else:
current_node.marked = 1
for node in current_node.references:
node_trace(node, node_dict)
def get_nodes():
# This function creates a dictionary of memory-blocks and named
# pointer-variables ncluding a "RootMemoryBlock" that hold the
# pointer-variables. The number of memory blocks/variables is
# determined by the contents of the input file.
#
# Each object is stored in the dictionary as a <MemoryObject>
#
# The contents of the input file are then used to determine all references
# between variables->blocks and blocks->blocks, with the only object
# referencing named-variables being the RootMemoryBlock. The format
# of the file garuntees that memory_blocks are listed as integers, and
# variables as strings that start with either a letter or an underscore '_'
#
# is_int is therefor used to determing if an object is a variable or a
# memory-block when populating the reference lists for the elements
# of the <MemoryObject> dictionary
#
# Each object's reference list is stored in its <MemoryObject>::references
# as a list of references to <MemoryObject>
#
# The dictionary is then passed into the node_trace function along with the
# RootMemoryBlock <MemoryObject> which recursively performs the
# "mark" phase of Mark/Sweep G.C.
#
# Finally a new dictionary is created and JUST the info for the
# memory-blocks (not variables, or the RootBlock) is copied into it.
#
# That dictionary is then returned to the calling function.
node_pointers = []
node_dict = {}
args = arg_parse()
input_file = args.filename
with open(input_file) as in_file:
node_count = 0
for line in in_file:
if node_count == 0:
node_count = int(line)
else:
split_line = line.rstrip()
split_line = re.split(r'[,]', split_line)
node_pointers.append([split_line[0], int(split_line[1])])
root_node_key = node_count
array_size = node_count + 1
for i in range (array_size):
node_dict[i] = MemoryObject()
# The format of the input file garuntees that each item will
# describe a link of the form [source, target]
SOURCE = 0 # The source of a reference link
TARGET = 1 # The target of a reference link
for item in node_pointers:
# PROBLEM CODE
if is_int(item[SOURCE]):
node_dict[int(item[SOURCE])].references.append(node_dict[item[TARGET]])
else:
if item[SOURCE] not in node_dict.keys():
node_dict[item[SOURCE]] = MemoryObject()
node_dict[item[SOURCE]].references.append(node_dict[item[TARGET]])
node_dict[root_node_key].references.append(node_dict[item[SOURCE]])
# /PROBLEM CODE
node_trace(node_dict[root_node_key], node_dict)
node_dict_final = {}
for element in node_dict.keys():
if is_int(element) and element != root_node_key:
node_dict_final[element] = node_dict[element]
return node_dict_final
def print_result(message, value, nodes):
# Displays the results of the mark/sweep algorithm
# as stored in the dictionary "nodes"
#
# Prints all marked nodes if value == 1
# Prints all reclaimed nodes if value == 0
print(message)
for element in nodes.items():
if element[1].marked == value:
if is_int(element[0]):
print(element[0])
def main():
# Entry Point function. Calls get_nodes which processes
# the input_file, then runs the simluated mark/sweep
# algorithm.
#
# It then displays the returned results of the mark/sweep
nodes = get_nodes()
print_result('\nMarked: ', 1, nodes)
print_result('\nReclaimed: ', 0, nodes)
print()
if __name__ == '__main__':
main()
截图:
答案 0 :(得分:0)
在函数is_int()
中,行:
elif s == 0
需要更改为
elif int(s) == 0
正确评估输入,因为参数是一个字符串,包含从文件读入的整数或变量名。这在任何非零整数的if
情况下都是隐式处理的,但需要在elif
零的情况下再次完成。